DroidScript
DroidScript
инструменты для мобильной разработки

20.06.2019

Thunkable X среда разработки

Thunkable X логика

Текст

Диалоги

Web-сервисы и API

Как создать многострочное поле ввода?

Для создания многострочного поля ввода можно использовать компонент Web Viewer. Скопируйте текст в текстовой блок.

data:text/html,<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1.0"/>
<html contenteditable="true">

Web Viewer

Недостатком этого решения является то, что для использования введенного текста в нативной части его придётся каждый раз копировать из Web Viewer. Но к преимуществу относится то, что клавиатура не убирается после каждого ввода символа перевода строки, как это имеет место быть при вводе текста в многострочное поле ввода (на iPhone5).

Как вывести текст с html-разметкой?

Нативные средства не позволяют использовать HTML и CSS для оформления текста, в отличие от компонента Web Viewer.

data:text/html,<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
initial-scale=1.0"/>
<style>
.myClass{color:red}
</style>
<h3>Заголовок</h3> <div class="myClass">Красная строка</div>

Web Viewer

Как отобразить системный диалог alert?

В последних версиях такая возможность была отключена. В качестве альтернативы можно использовать следующий код:

data:text/html,<meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<dialog><div style="width:100%;text-align:center">Alert</div>888-88-88</dialog>

Web Viewer

Как создать объект из JSON-строки?

Создание объекта из строки JSON

Ключевым моментом здесь является использование блока "create text with" (join) для корректной интерпретации строки, содержащей кавычки.

Как данные JSON добавить в список или область просмотра списка?

Данная задача часто возникает при работе с Firebase или WebApi, которые возвращают данные в формате JSON.

В Thunkable X существуют блоки для получения списка из текстовой строки с разделителями и для получения свойств объектов. Поэтому суть преобразования состоит в очистке исходной JSON-строки от лишних символов и приведение её к текстовой строке с разделителями.

Рассмотрим простой пример:

{
    "key1":"data1",
    "key2":"data2",
    "key3":"data3"
}

Для получения списка необходимо из этой строки удалить скобки { и }, а также кавычки. После этого строка превратится в пары значений, разделённые запятой, которую несложно превратить в список.

На практике общий алгоритм выглядит так:

1) Получить нужную JSON-строку
2) Очистить её от лишних символов и превратить во список
3) Создать цикл по списку, в теле которого выбрать из стоки нужные данные для отображения в ListViewer

Создание объекта из строки JSON

В случае использования сложной структуры JSON, символ запятой буде разделять не только объекты, но и поля, по причине чего её не получится использовать в качестве разделителя записей. Перед очисткой данных необходимо создать новый разделитель записей, например, заменив "}," на "}#", где # - разделителем записей.

Как исправить ошибку индексации списков List?

Из-за ошибки индексации списка (когда они начинаются от 0, а не от 1, как должно быть) блоки для получения и установки значений списка возвращают неверные значения. Для устранения этой ошибки можно использовать следующие блоки.

Коррекция ошибки индексации списков

Как работать совместно над одним проектом?

Средства для совместной работы в Thunkabke X отсутствуют, но есть возможность одновременно заходить в один и тот же аккаунт с разных рабочих мест. Это позволяет создать общий проект, который можно совместно обновлять. Проблема в том, что при одновременном редактировании проекта несколькими пользователями изменения будут сохранены только для одного из них, а все остальные пропадут. Выходом может служить последовательная работа над проектом, когда его редактирует один разработчик. Например, на первом экране совместного проекта создаётся надпись "Проект редактируется", под ним надпись с именем того, кто редактирует проект, а ещё ниже переключатель. При входе в проект редактор включает переключатель и указывает своё имя. Если кто-то откроет этот проект, то он увидит, что такой-то человек уже редактирует проект и нужно подождать своей очереди.

Более надёжным является подход, при котором выбирается руководитель группы (интегратор), которому остальные участники группы предоставляют доступ к отлаженным частям своих проектов, а он вручную объединяет их в окончательном приложении.

Как задать цвет помимо использования блока цвета?

Варианты установки цвета

Прозрачность изменяется от 0 до 1. Также возможно задать формате #rgb, #rgba, HSL (оттенок, насыщенность, яркость) или HSLA (c компонентой прозрачности), например:

#ff0
#f0f8
hsl(200, 100%, 50%)
hsla(200, 100%, 50%, 0.1)

Прозрачный цвет можно задать так:

rgba(0,0,0,0) или строкой "transparent".

Как преобразовать строку в число?

Для преобразования строки в число необходимо строку присвоить переменной, а затем при помощи блока сложения произвести сложение этой переменной с 0.

Преобразование строки в число

Преобразование происходит от начала строки до первого символа, не относящегося к числу. Для нечисловой строки будет возвращено значение NaN (не число). В качестве числа можно использовать строку в научной форме, например, 2e2 (200).

Как преобразовать число в булево значение?

Для этого используйте два блока отрицания not, например, not->not->1 (двойное отрицание используется для приведения значения к логическому типу). При этом только 0 даст значение false.

Как определить тип значения?

Общий алгоритм такой: над искомым значением производится некоторая операция. Если в результате получается некорректное значение, то предполагаемый тип не соответствует типу, для которого операция возвращает корректный результат.

Проверка на возможность преобразования значения к числовому типу.

Отпределения типа значения

Строгая проверка на число.

Отпределения типа значения

Для проверки на объект преобразуем значение в JSON и проверим наличие символа фигурной скобки.

Отпределения типа значения

Нежостаток данного способа.в том, что символ фигурной скобки можт присутствовать как часть строки. Другой спосоь состоит в использовании невидимого на экране компонента, тектовому блоку которого присваивается значение для проверки. Если передан объект, то в текстовом свойстве компонента будет строка [object Object].

Для проверки на строку можно использовать невидимый компонент, текстовому свойству которого присоединяется искомое через блок length of. Если передана не строка, то текстовое свойство компонента вернёт undefined.

Как копировать блоки между экранами одного приложения?

Для копирования блока выполните следующие действия:

  1. Выделите его и нажмите сочетание клавиш Ctrl+C.
  2. Перейдите на другой экран и нажмите сочетание клавиш Ctrl+V.

Копировать можно любые блоки, но следует учесть, что компоненты имеют локальную область видимости и не получится изменить их свойства из области редактирования блоков другого экрана.

Как вернуть случайно удалённые блоки?

Для отмены действий в редакторе блоков используйте Ctrl+Z или команду Undo контекстного меню, которое появляется при щелчке правой кнопкой мыши по рабочему полю редактора блоков.

При помощи данной команды невозможно отменить удаление компонентов.

Как в текстовую область или поле ввода вставить символ перевода на новую строку \n?

На iOS перевод строки в компоненте Lable и др. осуществляется при помощи символа Юникода line separator (U+2028). В Android это не работает, но один из пользователей нашёл универсальное решение для получения символа \n.

Имитация вставки символа новой строки

К сожалению, в ListViewer на Android этот способ также не работает.

Как скрыть компоненты на экране?

Существует несколько способов скрытия элементов:

  • Обнулить ширину и высоту - скрытие с освобождением занимаемой области
  • Сделать цвет фона и основной цвет прозрачными - скрытие без освобождения занимаемой области
  • Вращение вокруг оси Y на 180 градусов. Для этого на вкладке дополнительных свойств добавляем соответствующую трансформацию (если она существует для выбранного компонента) и установливаем для неё значение в радианах равным 3.14. В редакторе блоков можно воспользоваться блоком PI.
  • Поместить компонент в контейнер с нулевыми размерами - скрытие с освобождением занимаемой области
  • Расположить в конейнере с элементами, которые нужно скрыть, непрозрачную область (Column) с абсолютным позиционированием над скрываемыми элементами (непрозрачная крышка)

Как в текст добавить значки Юникода?

В настоящее время Thunkable X не поддерживает Font Awesome, но при помощи символов Unicode можно:

  • создать кнопку с пиктограммой
  • добавить значок к надписи на кнопке или в текст

Для этого необходимо открыть страницу с символами Юникода, найти нужный символ, скопировать его изображение и вставить в текстовое поле свойства компонента, текстовой блок, опцию списка и др. как показано ниже.

Символы Юникода

Вместо некторых значков в поле ввода может отображаться пустой пробельный символ.

Символы Юникода можно использовать, например, в элементах области списка List Viewer для имитации списка флажков или радиокнопок.

Как сделать ярлыки Tab Navigator с пиктограммами?

Для этого необходимо эмулировать ярлычковую навигацию при помощи кнопок:

  1. На каждом экране в верхнюю часть помещаем компоновщк Row и делаем его нижнюю границу заданного цвета.
  2. В компоновщик добавляем кнопки и распорки между ними - пустые Label заданной ширины
  3. В кнопки вставляем нужные пиктограммы - символы Юникода
  4. В редакторе блоков задаём переходы на экраны при нажатии на кнопки

Скриншот экрана iPhone.

Скриншот экрана iPhone c ярлыками

Преимущество программной эмуляции навигации состоит в том, что она позволяет отслеживать переключение экранов, тогда как компоненты навигации сделать это не позволяют.

Как сделать табличное форматирование?

В простейшем случае табличное форматирование делается с использованием моноширинного шрифта, который можно использовать в компонентах Label и Input Text. Алгоритм выглядит очень просто. В функцию форматирования передаётся строка и ширина столбца в символах. Внутри функции производится вычитание длины строки из ширины столбца и полученное значение используется для создания в цикле строки пробелов, которая затем добавляется к исходной строке. Если длина строки больше ширины столбца, то она усекается до его величины.

Табличное форматирование

Как создать пустой список и пустую строку?

Для создания пустых значений в блоках "create list width" и "join" открываем щелчком по пиктограмме шестерёнки контекстную панель настроек и удаляем из блока все опции.

Пустой список и строка

Как сохранять изменения при переключении экранов?

Для сохранения изменений экранов можно использовать либо компоненты навигации, либо локальное хранилище.

При использовании компонентов навигации, экраны в них инициализируются один раз перед своим отображением. При использовании блока "navigate to" экран, на который происходит переход, инициализируется заново и ранее сделанные в нём изменения на сохраняются. Например, если в поле ввода была введена строка, а затем осуществлён переход на другой экран, то по возвращению на этот экран полее ввода будет иметь значение по умолчанию, заданное в поле свойства или блоке инициализации. Для сохранения состояния экрана перед переходом на другой экран необходимо сохранить необходимые параметры в компоненте Local Storage, а в блоке "Screen Starts" - выгрузить их. При этом необходимо создать механизм инициализации по умолчанию, если запрашиваемые параметры в Local Storage отсутствуют.

Как расположить компонент в произвольной точке экрана?

Пока в Thunkable X нет блоков для позиционирования компонентов для этого можно использовать области с изменяемыми размерами. Изменение координаты Y спрайта производится изменением высоты компоновщика Column 16, а изменение координаты X - изменением ширины комноновщика Column 17, который вместе со спрайтом располагаются в компоновщике Row. Список возвращает строковые значения, которые при помощи математического блоков "round" преобразуются в числовые значения.

Абсолютное позиционирование

Как избавиться от перерисовки Image при работе таймера и др.?

Если в редактор блоков поместить обработчики событий ползунка или таймера, то при перемещении ползунка или активации таймера будет происходит перерисовка изображения в компоненте Image и дёргание разметки, что делает работу с таким приложением невозможным. Избавиться от этого бага можно путём замены компонента Image на кнопку или Column. Для запрета нажатия на кнопку используется техника прозрачной крышки - создаём Column под размер изображения, в него добавляем кнопку с фоновым изображением, поверх которой размещаем ещё один прозрачный Column с абсолютным позиционированием.

Как округлить число до заданной точности?

Округление с заданной точностью

Как сделать экран-заставку?

Создание экрана-заставки в Thunkable X не является очевидной задачей. Без использования компонентов навигации вместо экрана-заставки с большой вероятностью получится экран-ловушка (как в одном из официальных демонстрационных примерах и примерах пользователей): при помощи свайп-жеста есть возможность вернуться на данный экран, после чего будет невозможно перейти с него ни на какой другой экран, если на нём не используется блок перехода на другой экран.

При помощи компонентов навигации экрана-ловушки можно избежать, но тогда пользователь может сколько угодно раз открывать экран-заставку, в результате чего он уже не будет заставкой. Единственно верным способом создания экрана-заставки является помещение всех экранов в компонент навигации Tab Navigator, у которого отключена функция перехода по свайп-жесту. Для навигации между экранами в этом случае необходимо использовать блоки "navigate to".

Как правильно работать с асинхронным блоком?

Для последовательного обновления данных в FireBase пользователи часто испольуют циклы с задержкой. Такой алгоритм работы с асинхронными блоками является ненадёжным и приводит к разным ошибкам. Перед очередным вызовом асинхронного блока нужно убедиться в том, что предыдущий вызов прошёл успешно, что реализуется при помощи рекурсии.

Рекурсивный вызов асинхронного блока

В данном примере не производится проверка успешности операции записи, но в реальные проекты необходимо добавлять проверку на отсутствие сообщения об ошибке в локальном блоке error.

Как создать список переменных?

Список переменных можно использовать для динамического создания данных и упростить обмен ими между экранами.

Список переменных

Кто-то может заметить, что это не список переменных, а обычный список данных. Да, но в концептуальном смысле это список переменных.

Как создать приложение для прослушивания интернет радио?

Для прослушивания интернет радио необходимо знать ссылку на поток вещания. Для этого в поисковике вбиваем, например, фразу "наше радио ссылка на поток вещания" и вскоре её находим в выдаче "Наше Радио (128 kb\ps) - http://nashe1.hostingradio.ru/nashe-128.mp3". Можно также воспользоваться каким-либо сервисом интернет радио, например, https://www.internet-radio.com. Открываем его, находим интересующую трансляцию и копируем ссылку m3u.

После получения ссылки на поток или плейлист указываем её в свойстве WebViewer.URL - в центре области Web Viewer отобразится простой проигрыватель и начнётся воспроизведение потока. Прервать его можно нажатием на кнопку паузы в проигрывателе, а выключить его посредством перезагрузки страницы, присвоив WebViewer.URL строку "about:blank". Для отсечения выходящего за границы сообщения об ошибке в компоненте Web Viewer установите свойство overflow = hidden.

Снимок экрана в режиме воспроизведения интернет радио.

Снимок экрана в режиме воспроизведения интернет радио

Для простоты используем два списка, полученные путём копирования строк данных из Excel.

Алгоритм работы с интернет радио

Функциональность данного базового примера можно увеличить на свой вкус. Можно, например, разделить все трансляции по музыкальным стилям и сначала выбирать стиль, а затем поток. Можно дать пользователю возможность самому добавлять новые трансляции - создать экран для ввода названия и ссылки на неё с добавлением в список избранных и последующим сохранением в локальном хранилище. Также можно данные хранить в AirTable, создать систему оценки рейтинга трансляции и др.

Как при выборе элемента ListViewer получить всю запись?

Предположим, в списке List находятся записи, состоящие из нескольких полей. Если в ListViewer отображаются уникальные значения ключевого поля из данного списка, то при выборе ListViewer не составит труда получить соответствующую ей запись в List, даже в случае использования сортировки ListViewer. Для этого достаточно сделать цикл по всем записям List и сравнить текущее значение ключевого поля с выбранным значением из ListViewer.

Если в ListViewer отображаются не уникальные значения и используется сортировка, то определить запись не представляется возможным, так как индексы в List и ListViewer из-за сортировки совпадать не будут. Для выхода из этой ситуации необходимо в опциях ListViewer сохранять полные записи. Но тогда в ListViewer будут отображаться значения нескольких полей и разделители между ними. В случае использования iOS при помощи символа разрыва строки можно спрятать поля записи (расположив их на второй неотображаемой строке), но на Android символы разрыва в ListViewer не работают! В таких случаях можно использовать отформатированный код записи, содержащий индекс записи в List, например:

Вася [001]
Маша [100]
Вася [034]

Теперь независимо от сортировки получится точно определить нужную запись по коду выбранной опции.

Как сделать звонок или отправить SMS?

Для этого воспользуемся компонентом Web Viewer.

Код для телефонного звонка

Для отправки sms вместо tel: укажите sms:, а для звонка по скайпу - skype:. Остальные возможности можно посмотреть в справке по URL-протоколам.

Вместо компонента Web Viewer можно использовать блок "open link". При использовании блока "open link" запускается внешний браузер, на экране которого будут отображёны данные ресурса по указанной ссылке.

Сделать звонок, отправить почтовое сообщение, открыть ссылку в браузере, отобразить адрес на карте или добавить событие на указанную дату можно и при помощи компонента TextInput. Для этого на вкладке дополнительных свойств поля ввода укажите тип обнаруживаемых данных в полях dataDetectorTypes для превращения их в ссылки.

Как сделать плавающую кнопку действий?

В условиях отсутствия свойств видимости компонентов и некорректной работы редактора вида с позиционированием и отступами, решение данной задачи является настоящим экспериментированием с костылями.

Для создания кнопки и меню добавьте на экран два компонента Columns. В первом будет располагаться плавающая кнопка, а во втором - всплывающее меню.

Выбор режима позиционирования Columns производится на вкладке расширенных свойств Advanced панели свойств в категории Positioning, при открытии которой в поле Position нужно выбрать absolute. После этого выставляем нужные смещения в полях edgeOffsets и задаём значение в поле ZIndex, чтобы меню располагалось выше содержимого экрана..

Для скрытия элементов меню нужно в блоке инициализации экрана либо обнулять размеры контейнеров, их содержащих, либо обнулять размеры самих элементов меню, либо делать надписи и фон элементов меню прозрачными. Одного простого и работающего как на iOS, так и на Android решения здесь пока нет.

Как сделать кнопку с фоновым изображением?

У кнопки есть свойство для указания в нём фонового изображения, но в Thunkable X это не работает. В качестве альтернативы можно воспользоваться либо html-кнопкой в Web Viewer, либо кнопкой, расположенной над компонентом изображения. Для этого поместите компоненты Image и Button в компоновщик Row с размером по содержимому, а свойство Position для изображения установите в absolute.

Как сделать пользовательский диалог?

Создание пользовательского диалога основывается на абсолютном позиционировании контейнерного элемента, например, Column и инициализации у него свойства zIndex для отображения поверх других элементов на экране. На экран добавляем кнопку для открытия диалога и контейнер Column, внутрь которого добавляется List Viewer (для реализации List Picker).

Код для создания пользовательского диалога

Дополнение диалога тенью не так очевидно, как хотелось бы. Тень добавляется не контейнерному элементу Column, а рамке внутри него. Данная рамка создаётся при помощи пустого компонента Label с абсолютным позиционированием и относительными размерами 100% для того, чтобы она растянулась на всю область диалога. При этом List Viewer должен располагаться поверх Label.

Для реализации отмены диалога при нажатии за пределами его области расположите диалог над полноэкранной кнопкой (Button2), при нажатии на которую диалог будет закрываться.

Как получить координаты местоположения устройства?

Создайте файл geolocation.html со следующим кодом.

<script>
if (navigator.geolocation) {
	navigator.geolocation.getCurrentPosition(getLocation,getError);
}else{
	alert("Geolocation not supported");
}
function getLocation(position){
    var lat = position.coords.latitude;
    var lng = position.coords.longitude;
	alert("latitude: " + lat+"\nlongitude: "+ lng);
}
function getError(err){
	alert("Error code: " + err.code);
}
</script>

Код для определения местоположения устройства

Загрузите этот файл в проект и укажите его имя в свойстве Web Viewer.URL.

Как получить координаты при нажатии на маркер карты?

Как получить координаты при нажатии на маркер карты?

© 2016-2018 Александр Страшко