Jump to content

Yaroslav Brovin

Administrators
  • Posts

    2,584
  • Joined

  • Last visited

  • Days Won

    652

Blog Entries posted by Yaroslav Brovin

  1. Yaroslav Brovin
    Продолжаем анонсировать интересные возможности новой версии FGX Native 1.11.0.0. И в этот раз - это компонент локализации TfgTranslator.
    В этой версии мы поставляем отдельный bpl-пакет с компонентом локализации TfgTranslator, который мы сами уже давно и успешно используем в реализации FGX Native дизайнера. Однако, мы не рекомендуем его использовать в мобильных приложениях, поскольку все словари с переводами всегда загружаются при создании формы, а так же, поскольку у нас есть иное видение того, как должен осуществляться перевод в мобильных приложениях.
    Несмотря на сказанное - это рабочее решение, которое может помочь вам с локализацией ваших проектов. Мы поставляем этот компонент по правилу "as-is", то есть нет никаких гарантий (в том числе и поддержки) с нашей стороны по его работе. Этот пакет не является постоянным и может быть в будущем исключен из поставки при появлении рекомендованного решения.
    Как установить?
    Чтобы установить компонент локализации нужно выполнить регистрацию нового пакета компонента в среде. Для этого:
    Открываем менеджер пакетов: Main menu -> Component -> Install Packages. Нажимаем кнопку "Add..." Открываем каталог, где установлен FGX Native и открываем каталог, соответствующий версии вашей IDE. Если вы не меняли место установки библиотеки, то: "C:\Users\Yaroslav\AppData\Local\FGX Native\Libs\<версия IDE>\Win32\Release" Выбираем "FGXTranslatorD.<версия IDE>.bpl": Для 10.3 - 260 Для 10.4 - 270 Закрываем окно нажатием на кнопку OK. Теперь компонент TfgTranslator доступен для использования на панели "Pallette": FGX: Translator -> TfgTranslator.
    Как использовать?
    Компонент TfgTranslator выполняет перевод всех строковых свойств в рамках одной формы. Чтобы им воспользоваться, нужно бросить компонент на форму. Чтобы выполнить первичную настройку, необходимо создать список поддерживаемых языков и, по желанию, выполнить перевод текущих строк. 
    По двойному нажатию на компонент открывается редактор:

    Добавление языков
    По умолчанию, в компоненте есть только один язык "default", который используется для всех языков, если перевода нет. Вы можете добавить любое количество дополнительных языков. Для этого нажмите кнопку с глобусом и введите код языка (например "en").

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

    В столбце "Ключ" указаны уникальные идентификаторы переводимых строк, в остальных столбцах содержатся переводы на доступные языки.
    С большой долей вероятности, после сканирования строк, вам будет необходимо удалить все лишние строки. Вы можете это сделать при помощи кнопки Delete.

    Ручные строковые ресурсы
    Вы можете указать свои строковые ресурсы для использования их в рантайме. Для этого надо нажать на кнопку "T+" и указать код строки и ее переводы.


    Перевод
    Выполните перевод текущего словаря путем двойного нажатия на ячейку таблицы.

    Смена языка
    Смена языка осуществляется при помощи свойства TfgTranslator.LangId, где нужно указать нужный язык. При смене кода языка, компонент автоматически выполнит перевод указанных свойств.
    Русский (по умолчанию):

    Английский:

  2. Yaroslav Brovin
    Нам очень приятно поделиться с вами этой новостью. Одно из приложений, написанных на FGX Native, победило в ежемесячном конкурсе Delphi приложений от Embarcadero. Это приложение -  аудио-гид по достопримечательностям разных городов с поддержкой нескольких языков.
    Поздравляем Романа с успехом и желаем ему не останавливаться на достигнутом!
    Приложение в Play Market: https://play.google.com/store/apps/details?id=ru.wc2.welcome&hl=ru&gl=US Ссылка на конкурс Embarcadero: https://delphi.embarcadero.com/delphi26th-welcome-a-spectacular-mobile-app-for-travelers-made-in-delphi/ Автор: @Roman
  3. Yaroslav Brovin
    Добрый день пользователи FGX Native.
    Сегодня мы хотим рассказать про переход Android части библиотеки FGX Native на AndroidX. О том, что это, зачем это нужно и как это влияет на разработчиков мы поговорим в этой статье.
    Что такое AndroidX?

    Среди всех проблем Android - наверное, главной для разработчика является проблема адаптации мобильного приложения под все версии Android. Очень часто, в старых версиях Android просто невозможно реализовать тот или иной функционал, потому что операционная система не предоставляет для этого API. С выпуском новых версий, постепенно Google добавляет пропущенное API. Однако, при использовании такового, вы не можете запустить такое приложение на старых версиях Android, потому что оно просто упадет из-за отсутствия нужного API. Поэтому разработчикам нужно иногда писать по две реализации одного и того же функционала на разном API.
    Для того, чтобы это решить, Google стала выпускать набор библиотек, которые содержат универсальное API, работающее на всех версиях Android. Такая библиотека раньше называлась Android Google Support Library, а затем Google объявила ее устаревшей и заменил ее на новую AndroidX.
    AndroidX - Это набор библиотек от Google, в которых они расширяют стандартные скудные возможности Android и дают широкий набор нового функционала, доступный среди всех версий Android. Она включает в себя большое число разных библиотеки, начиная от реализации базовых компонентов Android OS, продолжая облегченной работой с камерой и заканчивая продвинутыми компонентами Material Design. 
    До версии FGX Native 1.15.0.0 используется "Android Google Support Library".
    Зачем переходить на AndroidX?
    Главная необходимость заключается в том, что многие другие современные сторонние библиотеки Android уже используют AndroidX. Например, Firebase, AdMob, Google Maps и тд. А это значит, что если мы хотим добавить новый функционал в TfgMap из свежих версий GoogleMap или добавить возможность отправки push-уведомления с картинкой из Firebase, то мы не сможем это сделать, пока не перейдем на AndroidX.
    Помимо внутренних потребностей для развития FGX Native на Android платформе нужно не забывать, что разработчик с FGX Native может использовать сторонние jar библиотеки, сгенерировать для них заголовочные файлы при помощи Java2Delphi утилиты (входит в поставку FGX Native) и использовать в вашем приложении вами любимый язык Delphi. Будь-то "Яндекс.AppMetrica" или WebRTC компоненты или UI компоненты, рисующие графики, FGX Native позволяет это сделать. Однако, опять же многие новые свежие версии сторонних Android библиотек уже используют AndroidX. А это значит, что их нельзя использовать, пока нет поддержки AndroidX.
    Почему переход на AndroidX не был выполнен ранее?
    Как уже было сказано ранее FGX Native до 1.15.0.0 использует "Android Google Support Library". И эта библиотека считается официально устаревшей с Июля 2017. Так почему же, мы до сих пор используем устаревшую версию?
    Перед тем, как ответить на этот вопрос, познакомимся, что технически означает "добавление Android библиотеки в приложение". Упрощенно, FGX Native Android приложение состоит из четырех частей:
    "SO-Библиотека" с нативным кодом вашего приложения. Это именно то, что получается в результате компиляции ваших форм, модулей и тд. "classes.dex" - Это байт код, который является стартовым для любого Android приложения. Именно эта часть загружает делфи библиотеку и передает ей управление. "Набор ресурсов" - иконки приложения, заставки, графические ресурсы, ассеты, шрифты, ресурсы локализации и тд, все то, что доступно для вашего приложения. "Манифест приложения" - это по сути описание содержимого вашего приложения, что оно может делать, а что нет. Именно он является определяющим файлом на предмет выдачи прав доступа, запуска других приложений и тд. Все это упаковывается и на выходе вы получаете пакет приложения APK или более сложный формат AAB.
    Android библиотека по сути имеет практически такое же содержание, как и Android приложение. Оно так же может иметь в своем составе нативные библиотеки, наборы ресурсов, манифест или же байт-код в jar-библиотеке.
    Поэтому чтобы добавить Android-библиотеку в приложение, необходимо все, что есть в библиотеке добавить в приложение. И выполнить хитрые манипуляции по совмещению данных из разных библиотеки (сливание манифестов, компиляция ресурсов, слияние байт кода в один classes.dex.
    Ресурсы, манифесты
    Так вот причина задержки в переходе на AndroidX кроется в механизме поддержки Android библиотек на уровне RAD Studio/Delphi. Добавление сторонних jar библиотек всегда было частью системы сборки Delphi, в которой мы увы не можем менять со стороны. Поддержка Android библиотек в Delphi ограничивается только добавлением байт кода в итоговый classes.dex. А это значит, что Delphi не умела и до сих пор не умеет сливать манифесты, добавлять  и компилировать ресурсы, внедрять so-библиотеки автоматически и тд. Поэтому круг использования сторонних Android библиотек в Delphi довольно узкий - это библиотеки, которые не используют ресурсы и по части не работают с UI. Как вы понимаете, таких библиотек в мире Android довольно мало. Потому что даже обычная не UI библиотека выделяет строковые ресурсы в "набор ресурсов" для возможности локализации разработчиком.
    Поэтому, чтобы выполнить миграцию на AndroidX нужно вначале реализовать полноценную поддержку Android-библиотек в Delphi. Поскольку это часть системы сборки Delphi, у нас нет возможностей для внесения изменений в не наш код. Осложняется еще и тем, что Delphi Deployment Manager заточен только на FMX и не любит никаких отклонений от "нормы" FireMonkey приложения. Поэтому IDE всячески пытается удалить, изменить, обновить элементы "Deployment Manager" и сводит практически на нет любые кастомизации.
    AndroidX является набором огромного количества маленьких библиотек, каждая из которых содержит свой набор ресурсов (изображения, стили, локализации, файлы настроек и тд). И именно по этому на нее не возможно перейти даже обходными путями.
    К сожалению, за прошедшие 5 лет выпуска Delphi больших изменений в области деплоя и сборки для Android не было. Главным изменением можно считать добавление поддержки MultiDex в Delphi 11.
    MultiDex и Delphi 11
    Если на пальцах объяснить, что такое MultiDex, то когда байт код из разных Android библиотек сливается в classes.dex, то может возникнуть ситуация, что все не влезает в один файл (ограничение накладывается на общее количество типов, методов и т.п., которое может поместиться в одном файле. Это связано с архитектурой выполнения байт кода в Android). Когда все не помещается в один файл, то остальное помещается в следующий файл classes2.dex и так далее, пока все не будет раскинуто по файлам. В этом случае apk содержит ни один classes.dex, а не сколько. И именно поддержка этого добавлена в Delphi 11. 
    По умолчанию, и FireMonkey и FGX Native приложение помещается в один classes.dex. Другими словами, прямой необходимости в поддержки MultiDex не требуется. Однако, чем больше сторонних Android библиотек вы используете, тем быстрее растет classes.dex и тем проще выйти за пределы SingleDex и перейти в MultiDex. 
    AndroidX вводит большое число зависимых библиотек, поэтому добавление AndroidX также автоматически добавляет необходимость использовать MultiDex. И если в Delphi 11, такая поддержка есть. То пользователям старых версий Delphi делать в этом случае уже нечего. Поскольку мы считаем, что разработчики не должны быть сильно привязаны к версии IDE при использовании нашего продукта, мы не могли и не можем отказаться от поддержки старых Delphi до 11 версии.
    Delphi 11 и FireMonkey поддерживает же AndroidX, в чем секрет?
    "Delphi 11 официально же использует AndroidX" - значит ли это, что проблем никаких нет? На самом деле, поддержка заканчивается только на уровне интеграции байт-кода в приложение. О чем я упомянул в предыдущем разделе. Это значит, что Delphi просто внедряет исполняемый байт код в приложение и так же не поставляет никакие ресурсы в FMX приложение. Как это отражается на приложении. Как только выполнение вашего приложения попробует обратиться к несуществующим ресурсам, то в этот момент оно может либо упасть, либо работать некорректно. Так же FMX содержит не весь AndroidX, а только минимально-необходимый набор библиотек. По большей части FMX минимально использует Android API, поэтому вы можете не наблюдать проблем с отсутствующими ресурсами. Однако, как только вы сделаете шаг в сторону и захотите расширить возможности добавлением Android-библиотеки, то вы поймете, что все использование ограничено и приложение не будет работать.
    Почему теперь переход на AndroidX стал возможен?
    Возможно, Embarcadero в будущем добавит полноценную поддержку Android-библиотек. Но пока ее нет, нам ничего не остается, как заменить систему сборки Android приложений на другую и добавить полноценную поддержку использования Android-библиотек. Последнее время мы плотно занимались этой работой. В результате чего мы полностью перешли с системы сборки Android приложения в Delphi на другую с полноценной поддержкой Android-библиотек. Данную поддержку вы увидите в обновлении 1.15.0.0. Подробности перехода на новую систему сборки будут рассказаны в следующей статье. Однако, новая сборка помимо полноценной поддержки Android-библиотек так же значительно ускоряет запуск приложения на устройстве (даже при условии деплоя ресурсов) и дает эти возможности на любой версии Delphi. Это значит, что клиенты любых поддерживаемых версий Delphi, не зависимо от IDE получат все возможности по сборке приложений, включая MultiDex и добавление Android-библиотеки.  
    Что дает нам AndroidX?
    Android 13 и новее
    Переход на последнюю версию AndroidX дает нам полноценную поддержки последних версий Android. Начиная с версии FGX Native 1.15.0.0 все приложения будут нацелены на Android 13 (Api Level = 33). Все заголовочные файлы так же будут обновлены до Android 13. Старые заголовочные с классами "Support Library" будут удалены.
    Material Components
    Помимо этого, теперь мы можем полноценно использовать компоненты из Material Design. И в будущем теперь нас ничто не сдерживает от добавления продвинутых различных реализаций вкладок, chips и т.д.
    Firebase
    Поддержка последней версии Firebase, работающая на всех поддерживаемых версиях Андроида без проблем. Возможность передавать изображение в push-сообщениях.

    Сканер штрихкодов
    Обновленная реализация сканера штрихкодов, которая работает быстрее, стабильнее и лучше.
    Карты GoogleMap
    Поддержка свежих версий карт.
    Реклама AdMob
    Использование последних версий площадки по размещению рекламы.
    Прочее
    Обновление Yandex.AppMetrica, Google SignIn, Billing, InAppPurchase и тд.
    Что делать, если я не все понял в этой статье?
    Не расстраиваться! FGX Native команда делает все, чтобы вам не нужно было знать обо всем этом и вы могли сконцентрироваться на решении своих задач. Однако, нам приятно поделиться с вами действительно важными изменениями в FGX Native, которые позволят нашему продукту стать еще шире и добавить еще больше новых возможностей. У нас большой опыт в этой области, который позволяет нам реализовывать практически любые идеи. 
    Всем спасибо за внимание!
  4. Yaroslav Brovin
    Добрый день, уважаемые разработчики.
    В этой статье мы поговорим о поддержке темной темы в FGX Native приложении, о том, как ее добавить, как сделать автоматическое переключение и о том, что добавлено в 1.15.3.0 в этой области.

    Введение
    Тема - это набор цветов и способов отрисовки компонентов. В светлой теме метка использует черный цвет текста и светлый фон, а в темной теме - наоборот, белый текст на темном фоне. Используя это правило, несложно настроить параметры отображения компонентов так, чтобы добавить темную тему.
     
    Для того, чтобы добавить темную тему буквально в один клик, мы предлагаем генератор темной темы в дизайнере ресурсов (Project -> FGX Assets Manager).

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

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

    Далее, если вы хотите использовать темную тему в вашем приложении, вы указываете ее название (имя, которое вы задали в дизайнере ассетов) в настройках формы через свойство ThemeName.

    Если вы хотите переключиться на светлую тему, то либо создаете аналогично отдельно светлую тему или же просто убираете присваивание темной темы для формы. И все казалось бы выглядит отлично. Однако, есть нюансы. И их здесь два:
    Не все нативные компоненты предоставляют настройки, при помощи которых можно полностью подстроить отображение компонента под темную тему. Нет возможности выполнить автоматическое переключение темы на основании системной темы. Если с настройками цвета текста все просто и очевидно, то с отрисовкой не все так однозначно. Операционная система самостоятельно рисует свои родные компоненты и умеет их отображать в зависимости от текущей системной темы. Сравните два скриншота окна выбора даты для темной и светлой темы.

    Если у кнопок и у меток вы можете поменять цвет шрифта, то с самим барабаном возникают вопросы, так как iOS не дает возможности для изменения цвета.  А значит вы не можете его корректно отобразить только при помощи цветов в FGX Native. И даже если вы примените темную тему FGX Native барабан у вас будет или с темным текстом или же он будет светлый для светлой темы, в результате чего стилизация будет некорректной.
    Темная тема на уровне системы
    Темная тема появилась в операционных системах довольно недавно, а значит возникает вопрос, а что делать с поддержкой темной темы в старых приложениях, которые не обновляются? И тут в iOS/Android поступают немного по разному.
    iOS
    Все новые приложения для iOS, которые нацелены на свежие версии iOS, где была уже добавлена тема, автоматически получают поддержку темной темы. Это значит, что система при старте приложения автоматически рисует нативный компонент согласно текущей системной темы приложения и также выбирает соответствующие системные цвета.
    Если разработчик не готов или не хочет использовать темную тему, то он явно указывает в настройках проекта UIUserInterfaceStyle = light. В этом случае, iOS рисует родные компоненты в светлой теме и игнорирует темную тему.  Мы используем этот режим в FGX Native, так как у нас не было полноценной поддержки темной темы. Поэтому все приложения FGX Native содержат этот флаг:

    Android
    Поддержка темной темы в Android более сложная. Она чем-то похожа на iOS, за исключением того, что некоторые производители Android устройств добавляют "свою" поддержку темной темы для старых версий. Например MIUI. В этом случае, производитель автоматом принудительно пытается применить темную тему и вычислить цвета на основании текущих (сделать их автоматический реверс). В результате кто-то из вас мог столкнуться с некорректным отображением приложения. Чтобы избежать этого мы принудительно отключаем все подобные попытки при помощи специального атрибута в стиле андроид приложения  
    <!-- MIUI automatically recolors UI in dark mode, it uses emulation mode. --> <item name="android:forceDarkAllowed">false</item> Выбор же темной темы в Android приложения строится на основании используемой темы приложения в файле styles.xml. По причинам отсутствия полноценной поддержки темной темы, мы так же используем строго светлую тему для Android приложения
    <!-- Basic theme for all Android versions --> <style name="BaseAppTheme" parent="Theme.AppCompat.Light"> Как добавить темную тему в FGX Native?
    Добавление темной темы состоит из нескольких шагов:
    1. Разрешаем FGX Native приложению автоматически использовать темную системную тему (Важно! FGX Native приложения не включают темную тему по умолчанию, поэтому требуется делать этот шаг).
    iOS: Удаляем ключ UIUserInterfaceStyle из настроек проекта: Project -> Options -> Version Info (для iOS конфигураций) Android: Меняем базовую тему в файле styles.xml (расположен в корне вашего приложения) cо значения "Theme.AppCompat.Light" на "Theme.MaterialComponents.DayNight"    <style name="BaseAppTheme" parent="Theme.MaterialComponents.DayNight"> Эти правки позволят приложению автоматически менять отрисовки нативных компонентов при смене системной темы.
    2. Добавляем светлую/темную темы в FGX Native через дизайнер ресурсов при помощи генератора тем:

    3. Отлавливаем изменение системной темы и применяем к форме тему из ресурсов. Для этого используем новое событие TfgForm.OnSystemAppearanceChanged, которое содержит параметры текущей системной темы и которое вызывается каждый раз при смене системной темы. 
    procedure TFormMain.fgFormSystemThemeChanged(Sender: TObject; const AAppearance: TfgSystemAppearance); begin case AAppearance.ThemeKind of TfgSystemThemeKind.Dark: ThemeName := 'Theme Dark'; TfgSystemThemeKind.Light: ThemeName := 'Theme Light'; end; end; Для того, чтобы при старте не накатывать тему из ресурсов еще раз, мы автоматически вызываем это событие каждый раз при открытии формы. Это позволяет ограничиться заданием темы только в данном обработчике.
    Если по каким-то соображениям, вы хотите узнать параметры системной темы, вы можете это сделать при помощи нового свойства FGX.SystemInfo.TfgSystemInfo.Appearance.
    Результат работы представлен ниже:
    video_2023-02-08_00-03-12.mp4 video_2023-02-09_22-47-34.mp4
    Планы на будущее
    В будущем мы будем стараться упростить этот процесс, чтобы темная тема на стороне FGX Native создавалась автоматически, если разработчик не использует темы в своем приложении, и она автоматически переключалась при смене системной темы.
  5. Yaroslav Brovin
    Добрый день, уважаемые разработчики. 
    FGX Native содержит большое количество разнообразных компонентов: начиная от визуальных компонентов, составляющих основу для создания UI вашего приложения, продолжая невизуальными компонентами, облегчающими отслеживание состояния вашего приложения  и заканчивая компонентами-интеграциями с различными сервисами. И если использование первых двух - не зависит от внешних сервисов, то третья - как раз часто требует настройки и более точной интеграции на стороне приложения.
    Так, например, при желании подключить Push-уведомления, вам нужно выбрать провайдера, выполнить первичную настройку на стороне сервиса и затем выполнить настройку клиента (FGX Native приложения). А при использовании Facebook аутентификации уже требуется гораздо больше действия, включая ручное подключение Android библиотек, добавление в деплой новых файлов, правку манифеста и тд.
    Отдельно стоит упомянуть про необходимость настроить приложение в целом: поменять заставку, настроить иконки и базовые цвета и так далее. Все это требует не столько кодирования, сколько внесения и размещения нужных значений параметров в манифесты и файлы настроек. К сожалению, эта часть настроек осуществляется при помощи штатного окна настройки проекта Project -> Options. И поскольку мы не имеем возможности его как-то модифицировать, то мы не можем добавлять туда новые настройки и адаптировать логику. 
    Именно по этой причине в этом релизе 1.18.0.0 нас ждет новое окно настроек проекта.

    Однако стоит обратить внимание, что просто новое окно настроек не имеет смысла без интеграции процесса сборки MSBuild. Так как введенные параметры и настройки нужно передавать и упаковывать в собираемого приложение.  В течении несколько месяцев мы разрабатывали базовый механизм для создания расширяемого окна настроек. Основная идея - это добавление любых страниц настроек и внедрение в систему сборки MSBuild для любых сторонних сервисов. В рамках разработки мы написали несколько расширений для MSBuild, чтобы в будущем проект можно было собрать полностью с командной строки. Процесс перевода в пользу сборки целиком с помощью MSBuild еще не завершен полностью, но мы движемся в этом направлении.
    В этой статье мы не будем разбирать API для сторонних разработчиков, которое они могут использовать для регистрации своих настроек, а сосредоточимся на утилитарном использовании.
    Анимированная заставка Android
    Первым главным нововведением нового окна настроек являются анимированные заставки для Android 12+. 
    https://developer.android.com/develop/ui/views/launch/splash-screen Начиная с Android 12+ структура заставок изменилась и теперь появилась возможность использовать современные анимированные заставки. Раньше была статья, которая описывала детально ручные правки, которые можно было внести 
    Сейчас достаточно включить опцию и настроить внешний вид заставки. Описание параметров смотрите в официальной документации Андроида.

    Eсли ваше приложение запускается на устройствах с Android 12+ будет использоваться анимированная заставка, на старых версиях Android, будет использоваться статическая заставка.

    Добавлен новый пример: "Android Api" -> "Анимированная заставка"
    Примечание: Настройки статической версии заставки пока находятся в старом окне настроек. По мере возможности мы будем переносить значимые для нас настройки из старого окна настроек проекта в новое.
    Google Maps
     
    Было: Раньше ключ карты указывался в стандартном окне настроек проекта в разделе VersionInfo. Помимо этого необходимо было включить поддержку карт в разделе "Entitlements List" -> "Maps Service".
    Стало: Теперь включение сервиса карт и API ключ указываются в разделе "Сервисы" -> "Google Maps".
    Что нужно сделать: Дополнительных действий не требуется. При открытии проекта в этой версии ключ будет автоматически перенесен. Однако, после этого ключ надо менять только в новом окне настроек.
    Facebook Login

    Было: Раньше при использовании "Facebook Login" необходимо было вручную вносить настройки Facebook Login в файлы "strings.xml" и "info.plist.TemplateiOS.xml". Так же требовалось вручную добавлять зависимость на Android библиотеку и править Android манифест.
    Стало: Достаточно включить сервис в новых настройках "Сервисы" -> "Аутентификация" -> "Facebook Login" и указать требуемые параметры.
    Что нужно сделать: Если вы уже используете Facebook Login, то вы либо можете оставить все, как есть. Либо же перейти на новую настройку. Для этого нужно откатить все изменения сделанные в статьях:
    Сервисы аутентификации. Аутентификация с помощью Facebook Login (Android) Сервисы аутентификации. Аутентификация с помощью Facebook Login (iOS). И выполнить включение и ввод настроек в новом окне.
    VK Login

    Было: Раньше при использовании "VK Login" необходимо было вручную вносить настройки в файл "info.plist.TemplateiOS.xml".
    Стало: Достаточно включить сервис в новых настройках "Сервисы" -> "Аутентификация" -> "VK Login" и указать требуемые параметры.
    Что нужно сделать: Если вы уже используете VK Login, то вы либо можете оставить все, как есть, либо же перейти на новую настройку. Для этого нужно откатить все изменения сделанные в статьях:
    Сервисы аутентификации. Аутентификация с помощью VK Login (iOS) И выполнить включение и ввод настроек в новом окне.
    Заключение
    В следующих релизах мы будем переносить значимые параметры - такие как настройки Push-уведомлений, реклама, аналитика и тд.
  6. Yaroslav Brovin

    Общая
    В ближайшие дни мы выпустим новый релиз FGX Native 1.9.0.0, в который будет включено большое количество разнообразных улучшений, новых возможностей и исправлений ошибок.
    TfgBottomSheetLayout
    Новый компонент, добавленный в 1.8.0.0, имел среди своих возможностей модальный режим отображения страницы.
    У текущей реализации модального режима есть одно ограничение, которое делает его не очень удобным для использования, а именно: у модального режима нет промежуточной стадии Collapsed (когда панель свернута в корешок, но при этом еще не блокирует основное содержимое).
    Мы решили разбить модальный режим на группу новых настроек:
    Настройки затемнения основной области содержимого TfgBottomSheetContent (TfgBottomSheetLayout.ContentShadingSettings). Теперь вы можете включать или отключать затемнение в любой момент времени, а также указать цвет, используемый для затемнения. Эта настройка особенно нужна при поддержке темной темы в вашем приложении.
    Настройка блокирования взаимодействия с основным содержимым компонента TfgBottomSheetLayout.BlockContentMode. /// <summary> /// <para> /// Режим блокирования получения любых событий основного содержимого <с>TfgBottomSheetContent</c>: /// </para> /// <list> /// <item><b>Never</b> - Никогда.</item> /// <item><b>WhenCollapsedOrExpanded</b> - Когда страница свернута или развернута.</item> /// <item><b>WhenExpanded</b> - Только когда страница разворачивается или развернута.</item> /// </list> /// </summary> TfgBlockContentMode = (Never, WhenCollapsedOrExpanded, WhenExpanded); Теперь при помощи этих двух настроек вы сможете гибко настроить модальный режим. Мы удалили старый метод ShowModal. Чтобы сделать его в 1.9.0.0 достаточно в дизайнере указать две настройки TfgBottomSheetLayout:
    BlockContentMode = WhenCollapsedOrExpanded ContentShadingSettings.Enabled = True. Буфер обмена
    Реализован новый кроссплатформенный сервис по работе с системным буфером обмена FGX.Clipboard.TfgClipboardService для Android и iOS. На текущий момент сервис позволяет работать только с текстом. Для ознакомления с работой сервиса доступен пример "Системные сервисы" -> "Текстовый буфер обмена".
    Темы
    Несмотря на то, что темы поддерживаются уже давно, с ними был ряд сложностей, связанных с использованием своих названий ресурсов. Смена темы автоматически работала отлично для всех компонентов, у которых разработчик не указывал свой ресурс. Однако, как только указывался любой ресурс (не по умолчанию), то такой ресурс считался независимым от темы и при переключении темы не менялся. Мы исправили эту ситуацию, и теперь ресурс привязывается к текущей теме формы, если ресурс указывается из текущей формы. Это позволяет сделать полноценное переключение темы для всех свойств. Если же ресурс не привязан к теме, то такой ресурс не будет меняться при смене темы у формы.
    Например, мы хотим кастомизировать оттенок панели навигации и хотим использовать "Dark Primary" цвет вместо "Light Primary". На скриншоте снизу мы указываем ресурс из текущей темы "Theme Light":

    Если же мы переключаем тему у формы со светлой на темную, наш вручную установленный ресурс оттенка панели теперь уже берет одноименный ресурс из темной темы.

    Дополнительно, мы решили слега помочь разработчику понять, какие ресурсы компонент использует по умолчанию. Теперь мы всегда отображаем название ресурса, используемого по умолчанию у свойства, даже если ресурса нет (если другое не указано). В старом подходе название ресурса по умолчанию отображалось только, когда в приложении есть тема. Однако, это не очень удобно, так как не дает возможности быстро узнать, какие ресурсы использует компонент по умолчанию и немного усложняет жизнь разработчиков. 

    TfgListMenu
    Это один из самых старых компонентов и в связи с разными идеями по его улучшению и развитию мы его не трогали. С одной стороны, это довольно удобный компонент для быстрого прототипирования меню, однако, с другой, он был ограничен в ряде настроек, которые позволили его бы слегка подстроить. Поэтому разработчики часто использовали TfgCollectionView вместо TfgListMenu. Мы решили ввести ряд базовых настроек, которые позволяют изменить базовую цветовую схему компонента, для полной совместимости с темами библиотеки.
    Добавлено новое свойство TfgListMenu.Appearance, которое предназначено для настройки цветовой схемы элементов пунктов меню.

    Данная группа настроек не позволяет раскрасить в разные цвета все пункты меню. Это связано с тем, что компонент следует концепции Material Design, где используется общая цветовая схема. Однако теперь, вы можете указать базовые цвета схемы и цвета для разделителя для обычного режима отображения пункта меню и выделенного, чего нельзя было делать ранее.
    Помимо этого, довольно часто, используемые иконки в пунктах меню, необходимо перекрашивать. Это можно было решить на уровне дизайнера ресурсов, просто указав для иконки нужный оттенок. Однако, используемые в меню иконки могут быть использованы в других местах на практике. В такой ситуации приходилось иметь два дубликата одной и той же иконки, но с разными оттенками, что безусловно увеличивает размер приложения и усложняет дальнейшую правку ресурсов. Ситуация осложняется, когда цвет иконки при выделении отличается от цвета иконки без выделения.
    Решение данной проблемы теперь лаконично сделано через новую группу настроек Appearance.Icon, работающей по такому же принципу, как и аналогичное свойство у TfgButton. Здесь вы можете указать цвет иконки без и с выделением. В результате вам достаточно иметь всего лишь одну иконку в ресурсах данного базового размера для всех остальных мест.

    Замер размера текста
    Еще одной из самых часто запрашиваемых возможностей с вашей стороны был функционал по программному замеру размера текста. В 1.9.0.0 появится набор методов у TfgCanvas предназначенных для получения размера текста:
    function MeasureText(const AText: string; const AMaxWidth: Single; const AIsWordWrap: Boolean): TSizeF; И многое другое...
    В релиз 1.9.0.0 включено большое количество правок iOS части в части управления формами, выравниванием и тд. 
  7. Yaroslav Brovin
    В ближайшее время выйдет новый релиз 1.7.0.0, главной новинкой которого станет новый компонент TfgBottomSheetLayout. Это специальный компонент для организации отображения дочернего содержимого через выдвигаемую панель с нижней части экрана. 
    Обо всех деталях использования компонента ниже.
    Структура
    Новый компонент доступен на вкладке "FGX: Layouts" -> "TfgBottomSheetLayout" и представляет собой композицию из трех частей, аналогичную структуре компонента TfgDrawerLayout:

    TfgBottomSheet - выдвигаемая снизу страница. TfgBottomSheetContent - контейнер для основного содержимого экрана.  TfgBottomSheetLayout - координатор, отвечающий за управление отображением страницы. Состояния и управление TfgBottomSheet
    Страница может находиться в одном из трех конечных состояний:
    Страница полностью открыта - TfgBottomSheetState.Expanded; Страница свернута, но видна ее часть - TfgBottomSheetState.Collapsed;  Страница полностью скрыта - TfgBottomSheetState.Hidden.    
    В любой момент времени текущее состояние страницы можно получить через TfgBottomSheet.State. А чтобы программно управлять страницей, можно воспользоваться следующими методами TfgBottomSheet:
    /// <summary> /// Полностью модально разворачивает панель с анимацией. Основное содержимое <c>TfgBottomSheetLayout.Content</c> /// недоступно.</summary> /// <remarks>Если панель открыта, то ничего не делает.</remarks> procedure ShowModal; /// <summary>Полностью разворачивает панель с анимацией.</summary> /// <remarks>Если панель открыта, то ничего не делает.</remarks> procedure Expand; /// <summary>Сворачивает панель до заголовка с анимацией. </summary> /// <remarks> /// Если у панели нет заголовка, то полностью скрывает панель с экрана. Если панель закрыта, то ничего не делает. /// </remarks> procedure Collapse; /// <summary>Полностью скрывает панель с экрана с анимацией.</summary> /// <remarks>Если панель уже полностью скрыта, то ничего не делает.</remarks> procedure Hide; Настройка скрытия
    Если вы хотите запретить полное скрытие страницы с экрана, вы можете это сделать при помощи свойства TfgBottomSheet.IsHideable. 
    /// <summary>Может ли пользователь полностью скрыть панель?</summary> property IsHideable: Boolean read FIsHideable write SetIsHideable default DefaultIsHideable; Настройка внешнего вида
    За высоту видимой части страницы в свернутом режиме отвечает свойство TfgBottomSheet.PeekHeight:
    /// <summary>Высота части панели, которая не задвигается целиком.</summary> /// <remarks>Работает в связке со свойством<c>Hideable</c>.</remarks> property PeekHeight: Single read FPeekHeight write SetPeekHeight stored IsPeekHeightStored nodefault; По умолчанию страница имеет непрозрачный фон. Однако, в определенных случаях, удобно использовать прозрачный фон. Таким образом можно добиться любой разметки вашего содержимого и добавить любые вложенные контейнеры. За прозрачный режим отвечает свойство TfgBottomSheet.IsTransparent.

    Модальный режим
    По умолчанию панель открывается и не блокирует основное содержимое. Вы можете продолжать взаимодействовать с контентом TfgBottomSheetContent. Таким способом обычно делают панели для отображения сопутствующей детальной информации https://material.io/components/sheets-bottom. Например:
        
    Однако, гораздо чаще используется модальный режим для организации контекстного меню или же открытия нового экрана:

    В этом случае, вам необходимо открыть страницу используя метод TfgBottomSheet.ShowModal.
    Демонстрационные проекты
    В 1.7.0.0 включены два демо-проекты, которые показывают использование модального и обычного режимов использования. Их вы можете найти в ветке "Компоненты" -> "TfgBottomSheetLayout".
  8. Yaroslav Brovin
    В процессе реализации уже существующих компонентов библиотеки FGX Native для iOS мы иногда сталкиваемся с тем, что для полноценной кроссплатформенной разработки приложений текущего функционала компонентов уже не хватает. Например, в панели TfgNavigationBar (iOS) для кнопки навигации часто иконку дополняют текстом, в то время, как в андроиде текст никто не добавляет. Однако, речь в этой новости пойдет не об этом компоненте, а об обычной кнопке TfgButton.
    С виду кнопка - один из самых простых компонентов. Однако, на практике, это довольно сложный компонент, если брать во внимание большое разнообразие в мире кнопок разных стилей и видов. Было много причин, почему кнопка TfgButton в библиотеке довольно ограничена в своих возможностях. Главная из них - это как сделать действительно удобный набор настроек, который угодил бы большинству и при этом был бы прост и гибок в настройке. 
    Рад поделиться, что в процессе реализации iOS и изучения Material Design,  мы пришли к удобному на наш взгляд набору настроек кнопки. 
    Стили
    Теперь кнопка может иметь один из трёх базовых стилей:

    Text - обычная текстовая кнопка, без рамки, с возможностью привязать иконку. Этот тип предназначен для третьестепенных действий. Outlined - это плоская Text кнопка с окантовкой. Этот же тип используется для второстепенных действий. Contained - это Outlined кнопка + заливка области. Естественно, каждый вид кнопки должен иметь свой индивидуальный набор настроек. И желательно, чтобы инспектор объектов отображал только актуальные для данного стиля настройки. Так, например, если используется Text кнопка, то для нее должны быть доступны настройки рамки и заполнения.
    Поэтому теперь каждый стиль кнопки динамически подгружает свой набор настроек. Выбор стиля выполняется в инспекторе объектов в новом свойстве Appearance:

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

    Настройки элементов
    Стоит отметить, что теперь можно отдельно управлять отображением каждого элемента кнопки:
    Текст Иконка Рамка Наполнение Таким образом, теперь для иконки можно отдельно указать оттенок прямо на уровне компонента. Это особенно удобно в случаях, когда вы используете одну и ту же иконку в разных местах с разными оттенками. Если ранее для решения подобной задачи было необходимо делать копии одной и той же иконки и менять ей оттенок в дизайнере ресурсов, то сейчас достаточно установить свойство Appearance.Icon.TintColorName равным "Theme\Text\Icon" (к примеру).

    Так же теперь можно указать желаемый размер области вывода иконки. В автоматическом режиме, иконка старается стать как можно больше, занимая все доступное пространство кнопки. При указании фиксированного размера, иконка не сможет превысить указанное значение:

    При этом, кнопка с Contained стилем умеет автоматически подбирать цвета текста и иконки на основании цвета фона (если вы не указали свои цветовые предпочтения явно?

    Помимо этого, если вы хотите отобразить цветную иконку, вы можете отключить автоматическую перекраску через свойство Appearance.Icon.RenderMode.

    Для рамки кнопки мы предусмотрели возможность изменить значение радиуса скругления и толщину рамки.

    Изменения API
    Переименованы свойства ImageName -> IconName, ImageLocation -> Appearnace.Icon.Location, так как на наш взгляд иконка - это небольшой графический элемент, который преимущественно отображается на кнопке. При этом мы оставили обратную совместимость, так что при запуске старого проекта, старое значение из свойства ImageName и ImageLocation будет автоматически прочитано. Свойства TextSettings и TextShadow теперь находятся в группе настроек Appearance.Text. Они так же будут успешно восстановлены для старых проектов. Старые типы кнопок TfgButonKind.Raised и Flat теперь не будут поддерживаться и при открытии проекта автоматически будут сконвертированы в Contained и Text стили. P.S. Всем хороших выходных и успешного кодирования ?
  9. Yaroslav Brovin
    На этой неделе всех нас ждет большой релиз библиотеки FGX Native 1.6.0.0, в который войдет много новых вещей и самое главное - Альфа версия iOS! 
    Вкратце обо всех нововведениях по порядку:
    FGX Native for iOS (Alpha)
    Это свершилось! Релиз 1.6.0.0 будет содержать Альфа версию FGX Native for iOS.
    Важно. Поскольку это альфа версия, то не стоит ожидать от нее полноценной работоспособности. Данный релиз содержит частично реализованный функционал: часть компонентов пока не реализованы, часть функционала компонентов может не работать. Однако, при этом, часть компонентов уже полностью готова.
    Теперь все проекты автоматически получают новый таргет iOS Device 64-bit. При открытии старого проекта, происходит автоматическая миграция проекта, в ходе которой:
    Добавляется платформа iOS Device 64-bit для сборки Добавляется конфигурация для деплоя iOS приложения. Добавляются настройки проекта, связанные с iOS (иконки, название пакетов и тд) Добавляются ассеты для iOS.  
    В дизайнере пока нет возможности переключиться на стиль iOS. Это будет добавлено уже ближе к полноценному релизу iOS части. 
    На текущий момент:
    Минимальная поддерживая версия iOS 11.  Не реализованы следующие компоненты : TfgCalendar, TfgAutoCompleteEdit, TfgSearchBox, TfgWebBrowser, TfgVideoControl, TfgCamera, TfgCameraPreview, TfgBarcodeScanner. Не реализована анимация. Не реализованы жесты. и тд Важно. Для сборки проекта необходимо использовать SDK не выше 13.5. С более старшими версиями SDK вы получите ошибку при линковке приложения. Мы уже занимаемся этим вопросом.
    За время разработки iOS версии у нас накопилось большое количество изменений, которые затрагивают не только iOS реализацию, но и некоторые аспекты работы библиотеки в целом.

    В процессе приходят новые идеи по улучшению уже существующего API компонентов.  Чтобы не копить все изменения отдельно от текущей версии библиотеки, мы решили соединить все изменения по iOS с текущим релизом. Так что теперь вы всегда будете в курсе текущего состояния iOS части.
    Мы ценим терпение и поддержку наших клиентов. Поэтому, поскольку релиз FGX Native for iOS немного задерживается, мы приняли решения, что не будем увеличивать цену за продление подписки в момент релиза полноценной iOS для клиентов, которые на момент релиза будут иметь активную подписку.  
    Т.е. если на момент полноценного релиза iOS у вас есть активная подписка, то стоимость продления для вас останется прежней. Для всех остальных стоимость первоначальной подписки и продления будет увеличена.
    Начиная с 1.6.0.0 мы будем включать в каждый релиз список доработок по iOS, чтобы вы всегда были в курсе.
    Обо всех найденных ошибках вы сможете сообщить нам в новой ветке форума https://forum.fgx-native.com/forum/102-ios-alpha-тестирование/. Так же в ней вы можете высказать свои пожелания по приоритету разработки того или иного функционала. Это поможет нам составить список первоочередных задач и сфокусироваться на действительно важных для вас задачах.
    Полностью переработанная кнопка TfgButton
    В дополнение к статье необходимо упомянуть, что у кнопки есть еще один важный стиль, о котором не говорилось ранее - Default. В этом стиле кнопка выглядит так, как это принято на целевой платформе. На Android - это закрашенная кнопка, в iOS - это текст без фона. Используйте этот стиль, если хотите придерживаться системного стиля отображения кнопки.  
      
    Ранее у кнопки вы могли наблюдать внутренние отступы между ее границей и фоном. Это в свою очередь немного усложняло позиционирование кнопки по отношению к другим компонентам. Поэтому в этом релизе мы убрали у Android кнопки все отступы между границей компонента и фоном. Если вы использовали эти отступы при выравнивании компонентов вашей формы, вам следует задать эти отступы напрямую через TfgButton.Margins.
    Небольшие улучшения в дизайнере
    В дизайнер добавлен ряд косметических улучшений, чтобы нашим пользователям было приятнее работать и ничто не отвлекало их от решения задач. Среди улучшений темная тема для дизайнера форм.

    А так же вспомогательная подсказка, отображающая имя выделенного компонента. Подсказка появляется при нажатии на компонент.

    Правила обрезки текста (TfgTextTrimming)
    В первоначальной версии библиотеки мы закладывали несколько способов обрезки текста: по символам, по словам и без обрезания. Однако, в результате реализации iOS и Android оказалось, что обрезка текста по словам не используется и не поддерживается ни на одной из платформ. Поэтому в данном релизе мы решили убрать значение TfgTextTrimming.Word, так как оно не работало и не имеет смысла. Если вы использовали в своих проектах TfgTextTrimming.Word, то вам необходимо переоткрыть формы, проигнорировав ошибку, и сохранить формы заново. 
    Канва TfgCanvas
    Мы добавили два важных метода, которые теперь НЕОБХОДИМО использовать при выполнении любой отрисовки на TfgBitmap - это TfgCanvas.BeginPaint и TfgCanvas.EndPaint. При вызове этих методов происходят определенные действия по переносу данных битмапа между буферами для ускорения работы с изображениями в целом. Если в уже существующем коде вы не расставите эти методы, то на iOS платформе вы не увидите результат отрисовки.
    Небольшой пример по использованию новых методов BeginPaint/EndPaint для отрисовки иконки: 
    Scale := TfgScreenManager.Main.Scale; IconSize := Ceil(DefaultIconSize * Scale); FMoreIcon := TfgBitmap.Create(IconSize, IconSize); FMoreIcon.Scale := Scale; with FMoreIcon.Canvas do begin BeginPaint; try Fill.Kind := TfgBrushKind.Solid; Fill.Color := TAlphaColorRec.Black; FillCircle(TPointF.Create(6, 12), 2); FillCircle(TPointF.Create(12, 12), 2); FillCircle(TPointF.Create(18, 12), 2); finally EndPaint; end; end; Помимо этого, добавлены упрощенные методы для отрисовки скругленных прямоугольников:  TfgCanvas.DrawRoundRect/FillRoundRect.
    Basic Аутентификация в TfgWebBrowser
    Для браузера по запросу добавлена поддержка Basic аутентификация. Чтобы выполнить аутентификация, достаточно задать свой обработчик на новое событие OnBasicAuthentificationRequest, в которое передается специальный AHandler, отвечающий за процесс аутентификации. Процесс аутентификация может выглядеть так:
    procedure TFormMain.fgWebBrowser1BasicAuthentificationRequest(Sender: TObject; const AUrl: string; const AHandler: IFGXBasicAuthentificationHandler); begin TfgDialogs.InputQuery('Input credentional data', ['User name', 'Password'], ['', ''], procedure (const AResult: TModalResult; const AValues: TArray<string>) begin if AResult = mrOk then AHandler.Proceed(AValues[0], AValues[1]) else AHandler.Cancel; end); end; Если аутентификация не прошла, то браузер будет пытаться пройти ее повторно, повторно вызывая OnBasicAuthentificationRequest. 
    Новые параметры экрана TfgScreen
    Для TfgScreen добавлен новый параметр SafeAreaPadding, который позволяет узнать, какие области на экране заняты системными элементами. Если раньше эти отступы можно было получить только в событии формы TfgForm.OnSafeAreaChanged, то теперь их можно получить в любой момент с помощью TfgScreenManager.Main.SafeAreaPadding.
    Tip: Не забывайте, что коэффициент масштабирования экрана всегда можно получить кроссплатформенным способом через TfgScreenManager.Main.Scale.
    Другие улучшения
    В этом релизе также содержится большое количество исправлений ошибок. 
    Всем спасибо за внимание!
  10. Yaroslav Brovin

    Общая
    В ближайшем релизе 1.5.0.0 мы добавили пару небольших улучшений, которые немного помогут вам проще разрабатывать ваши мобильные приложения.
    1. Отступы для TfgLabel
    В разработке пользовательского интерфейса довольно часто встречается задача визуального выделения текстовых меток/тегов. Обычно для визуального выделения используется фон в виде скругленного прямоугольника.
     
    Раньше такая задача решалась при помощи двух компонентов:
    Контейнер TfgLayout с требуемыми отступами для текста и с фоном BackgroundName в виде 9-path изображения. Метка TfgLabel, куда непосредственно выводится текст. Теперь же у TfgLabel есть специальное свойство ContentPadding, позволяющее добавить внутренние отступы, используемые при отображении текста. В результате метка легко получается на базе одного компонента TfgLabel с фоном BackgroundName  и требуемыми отступами.

    2. Оттенок для кнопки TfgButton
    Теперь для кнопки TfgButton добавлены новые свойства TintColor и TintColorName, позволяющие перекрасить системный цвет кнопки.

    3. Android AlarmManager
    Мы добавили небольшой пример по использованию Java кода из  FGX Native приложения. Новый демонстрационный пример показывает, как сделать на языке Java свой BroadcastReceiver и использовать его в связке с FGX Native приложением. Данный пример пригодится разработчикам, которым необходимо более тесная интеграция с Android API.
    4. Автосайз
    iOS
    Так же мы с нуля реализовали TfgDrawerLayout для iOS
    drawer-iOS.mp4.648b868510783b05479fa65efce46878.mp4
  11. Yaroslav Brovin
    Всем доброго дня!
    У нас есть много хороших новостей на конец уходящего лета ?.
    Во-первых. Мы практически полностью разработали новые компоненты под iOS TfgNavigationBar, TfgListMenu, TfgDatePicker, TfgTimePicker, TfgTimeEdit, TfgDateEdit, TfgCheckBox, TfgRadioButton, TfgPageControl, TfgTrackBar, TfgRectangle, TfgLine, TfgSvgPath и тд. Закончили с TfgCollectionView и реализовали полноценную поддержку стилей, "Drag & Drop" и "Pull To Refresh".
    reordering.mp4.1e0e3a9268a4c8a4cb40e3a8b75d6b03.mp4 pull-to-refresh.mp4.87c902179beda7dacf55c9f028c06423.mp4
    Во-вторых. Мы реализовали полноценную TfgCanvas для iOS с поддержкой градиентов, разных кистей и отрисовкой на битмапах.
    В-третьих. Мы улучшили поддержку TfgPath. И теперь мы полностью поддерживаем весь стандарт доступных path команд w3c.
    В-четвертых. Реализовали диалоги и пикеры для выбора даты и времени.
    В-пятых. Реализовали TfgForm.OnSafeAreaChanged и добавили возможность получать состояние приложение напрямую у TfgApplication.State.
    В-шестых. Запустили FGX Native Global Demo и большая часть экранов уже открывается и успешно работает.
     
    Всем хорошего окончания этих выходных!
  12. Yaroslav Brovin
    Всем доброго дня!
    Как и обещал ранее, перед релизом 1.4.0.0 выкладываю инструкцию о миграции использования старого Android-Delphi моста на новый в 1.4.0.0. Это руководство актуально тем разработчикам, которые используют Android Api в своих проектах. В этой статье я рассмотрю только те аспекты в работе моста, которые изменились.
    По большей части изменения были необходимы только в свете поддержки RAD Studio 10.4, в которой была полностью удалена поддержка модели памяти ARC.
    1. Создание Java объекта:
    Было:
    var Intent: TJIntent; Intent := TJIntent.Create; Стало: 
    var Intent: JIntent; Intent := TJIntent.Create; Все объявления переменных, атрибутов и тд должны быть теперь именованы без префикса "T". TJActivity -> JActivity.
    2. Передача Java объектов через Java интерфейс:
    Было:
    // Декларация метода. Принимает атрибут интерфейсного типа CharSequence. TJTextView.setError(const AArg0: JCharSequence); // Java cтрока TJString реализует интерфейс JCharSequence. Поэтому передача идет напрямую (в старой версии моста). View.setError(StringToJString(Control.Error)); Стало:
    // Декларация метода. Принимает атрибут интерфейсного типа CharSequence. TJTextView.setError(const AArg0: JCharSequence); // Теперь обертка Java cтроки TJString НЕ реализует явно интерфейс JCharSequence. Поэтому необходима явная конвертация JString -> JCharSequence View.setError(TJCharSequence.Wrap(StringToJString(Control.Error))); // Или можно воспользоваться хелпером из FGX.Helpers.Android.pas View.setError(StringToJCharSequence(Control.Error)); 3. Работа с Java массивами:
    При создании экземпляра Java массива (TJavaArray<T>) вся работа теперь осуществляется через интерфейс IJavaArray<T>.
    Было:
    var Points: TJavaArray<Single>; Points := TJavaArray<Single>.Create(0); FCanvas.drawLines(Points, FStroke); Стало:
    var Points: IJavaArray<Single>; Points := TJavaArray<Single>.Create(0); FCanvas.drawLines(Points, FStroke); 4. Работа с Java-листенерами:
    Если вы реализовывали свои листенеры через наследование класса Java.Bridge.TJavaLocal, то в 1.4.0.0 листенеры теперь поддерживают счетчик ссылок через Delphi IInterface. Это значит, что при создании листенера, его необходимо сохранять в переменную/поле интерфейсного типа, а не объектного.
    Было:
    TfgAndroidCameraStateListener = class(TJavaLocal, JCameraStateListener) private [Weak] FCamera: TfgAndroidCamera; public constructor Create(const ACamera: TfgAndroidCamera); { JCameraStateListener } procedure onClosed(const AArg0: JCameraDevice); procedure onDisconnected(const cameraDevice: JCameraDevice); procedure onError(const cameraDevice: JCameraDevice; const errorCode: Integer); procedure onOpened(const cameraDevice: JCameraDevice); end; var FStateListener: TfgAndroidCameraStateListener FStateListener := TfgAndroidCameraStateListener.Create(Self); FStateCallback.setListener(FStateListener); Стало:
    TfgAndroidCameraStateListener = class(TJavaLocal, JCameraStateListener) private [Weak] FCamera: TfgAndroidCamera; public constructor Create(const ACamera: TfgAndroidCamera); { JCameraStateListener } procedure onClosed(const AArg0: JCameraDevice); procedure onDisconnected(const cameraDevice: JCameraDevice); procedure onError(const cameraDevice: JCameraDevice; const errorCode: Integer); procedure onOpened(const cameraDevice: JCameraDevice); end; var FStateListener: JCameraStateListener FStateListener := TfgAndroidCameraStateListener.Create(Self); FStateCallback.setListener(FStateListener); В противном случае, экземпляр листенера FStateListener будет удален сразу же после вызова 
    FStateCallback.setListener(FStateListener); Что в свою очередь приведет к последующим падения приложения. Так как сработает механизм подсчета ссылок Delphi интерфейсов. 
    5. Конвертация string <-> JString:
    До RAD Studio 10.4 мобильные компиляторы поддерживали добавление операторов неявного преобразования. Это в свою очередь позволило нам реализовать автоматическую конвертацию "на лету" Delphi string <-> Java JString. В 10.4 эту возможность убрали вместе с ARC, так как неявное преобразование реализуется через ARC. Поэтому теперь нужно явно вызывать преобразование строк через StringToJString и JStringToString:
    Было:
    TjUri.parse('tel:+'); Стало:
    uses FGX.Helpers.Android; TJUri.parse(StringToJString('tel:+')) Это все изменения, которые необходимо сделать.
  13. Yaroslav Brovin
    Всем хорошей пятницы,
    Немного новостей с полей разработки iOS ?. Мы продолжаем активно работать над реализацией iOS части библиотеки FGX Native и хотим поделиться с вами текущим статусом ?.
    1. Полностью реализованы новые компоненты
    TfgScrollBox, TfgVerticalScrollBox, TfgHorizontalScrollBox, TfgCardPanel, TfgSwitch, TfgTimer
    CardPanel-Demo.mp4.c88e1292626fcdf90ba849929b1bc238.mp4
    2. Частично реализована поддержка TfgBitmap
    Реализованы базовые операции с TfgBitmap: 
    Создание. Работа со скейлом Чтение из разных источников. Сохранение. 3. Добавлена поддержка ресурсов
    Научили iOS приложение работать с нашими ресурсами. Теперь app пакет содержит ресурсы FGX Native приложения.
    4. Реализованы вспомогательные сервисы
    Реализована часть служебных сервисов (IFGXLocaleService, IFGXApplicationInfoService, IFGXScreenService) используемых, в том или ином виде в существующих компонентах и вспомогательных классах.
    5. Частично реализован TfgCollectionView
    Реализована базовая функциональность списка. Создание элементов. Поддержка стилей. Связывание данных. 
    collectionView-3.mp4.3594030bf632722305b29ae89b970b55.mp4 CollectionView.mp4.83702aa8066d5e7d28cb2594fa9c56a9.mp4
    6. Частичная реализация TfgImage
    Реализованы все методы отображения изображений, кроме маски.
    7. Реализация диалогов
    Реализованы диалоговые окна TfgDialogs для отображения сообщений и диалогов с кнопками.
    8. Добавлены новые хедеры для iOS 13.
    Транслированы и добавлены свои собственные хедеры для iOS API.
  14. Yaroslav Brovin
    и 
    Что связывает итальянскую конференцию DelphiDay по Delphi и FGX Native?
    Правильно! В ближайшие дни FGX Native будет представлена на одной из крупнейших Delphi конференций Европы в Италии, на родине Марко Канту. Это очень важный шаг в истории развития проекта, потому как библиотека постепенно выходит на международный уровень. Возможностью рассказать о себе широкому кругу иностранных разработчиков мы обязаны нашему клиенту из Италии @claudio.piffer, который сам проявил инициативу и подготовил интереснейшую презентацию о  FGX Native. В данной презентации  Клаудио расскажет о главных возможностях библиотеки и поделится своими впечатлениями об её использовании. 
    От всего сердца желаем Клаудио удачи и с нетерпением ждём его выступления.
    Ниже опубликована вся информация о конференции.
    P.S. Выступление будет на итальянском.
    Когда: 11 июня 12:30 (по московскому времени) Программа конференции: https://www.delphiday.it/ Язык: итальянский Заголовок: FGX Native: мобильная альтернатива FMX Спикер: @claudio.piffer  Анонс:
  15. Yaroslav Brovin
    Всем доброго дня,
    Немного полезной технической информации о следующем релизе 1.4.0.0:
    Поддержка RAD Studio 10.4
    Новый релиз будет посвящен поддержке RAD Studio 10.4 с одной стороны и прекращению поддержки RAD Studio 10.2 с другой стороны. Основные причины:
    Отсутствие жизненно важной поддержки Android 64-bit Нет поддержки push-уведомлений на уровне IDE Новый Java-Delphi мост
    В версии 1.4.0.0 будет полностью обновленный Android-Delphi мост. Он будет основан на нашей текущей реализации моста. Однако он не будет совместимость со старыми заголовочными файлами.
    Это значит, что если вы используете нативное Android API в ваших приложениях, то в версии 1.4.0.0 нужно будет выполнить миграцию. Миграция будет простой. Инструкция будет детально дана ближе к релизу.
    Причина обновления моста связана с удалением поддержки ARC в 10.4. Это приводит к нерациональному и неоправданному использованию делфи классов, как обертки над Java классами. Так как, используя такой подход, необходимо удалять руками все объекты моста. При этом код становится очень тяжелым для восприятия и неудобным для использования. 
    Обновленная версия моста будет улучшенным синтезом нашей текущей реализации и подхода с использованием делфи интерфейсов. Он сохранит все принципы работы с классовыми членами (поля, методы) и способом создания Java объектов. Однако теперь работа с созданным объектом будет осуществлять через интерфейс, а не класс, как было ранее.
    Всем спасибо за внимание и хорошего рабочего дня!
  16. Yaroslav Brovin
    Мы стараемся делать так, чтобы FGX Native стала эффективным инструментом ? для разработчиков, приносила результаты и доставляла удовольствие от работы ?.
    Мы постоянно работаем над расширением возможностей и предоставляем новый функционал. Однако, с учетом молодости проекта FGX Native по нему не так много информации.
    Эффективность использования зависит от ваших умений и навыков. А для развития этих умений и навыков нужны обучающие материалы ?‍?, примеры правильного использования.
    Мы решили провести небольшой пробный эксперимент и для начала записать пару обучающих видео уроков по использованию FGX Native.
    Рад представить вам первый, самый базовый урок для начинающих о начале разработки мобильных приложений с FGX Native и Delphi. В уроке рассматривается:
    Настройка рабочего окружения; Создание Hello World мобильного приложения; Запись и чтение логов в FGX Native. Следующий урок будет о системе выравнивания Flex в FGX Native. Рассмотрим типовые задачи и их решения. Сверстаем сложный макет приложения. Чтобы не пропустить, подписывайся на новый официальный канал FGX Native: https://www.youtube.com/channel/UCd818Et5Fi0Iy53YouBce3w 
    Приятного обучения:
     
  17. Yaroslav Brovin
    Сложно представить мобильное приложение без графических ресурсов. Поиск иконок зачастую становится довольно сложной и не тривиальной задачей, особенно с условием необходимости найти иконки в разных масштабах, чтобы они четко выглядели на любых устройствах клиентов. 
    Мы подумали, что можем помочь вам с этим и сэкономить время, которое вы можете потратить на что-то более важное. Теперь вы сможете в пару кликов добавить современные иконки в ваше приложение через дизайнер ресурсов FGX Native.


    Около 1000 вариантов уникальных иконок доступно вам в 4 различных размерах (18х18, 24х24, 36х36 и 48х48). Каждая иконка поддерживает 5 варианта скейлов (1.0, 1.5, 2.0, 3.0 и 4.0) для каждого базового размера и специально разработана с учетом Материал дизайна для Андроид приложений.
    В будущем наборы иконок будут расширяться и появляться новые.
    Возможность появится в 1.1.6.0. Не пропусти!

  18. Yaroslav Brovin
    В обновлении 1.1.6.0 процесс сборки android приложения претерпел незаметное на первый взгляд, но очень важное для пользователей изменение, а именно,  добавлена автоматическая генерация файла classes.dex.
    classes.dex - обязательный для android приложения файл, содержащий все используемые в приложении Java библиотеки. Ранее конечное приложение собиралось с готовым classes.dex файлом поставляемым вместе с библиотекой FGX Native, что создавало для разработчиков некоторые проблемы при использовании сторонних jar библиотек. Процесс добавления был нетривиален и требовал глубокого погружения в документацию, процессы сборки и микширования classes.dex.
    Механизм автоматической генерации уже используется в FMX проектах, однако, по ряду причин и ограничений, накладываемых IDE, он не мог быть задействован для FGX Native.
    Мы пересмотрели пользовательский опыт и рады представить вам новый удобный диалог для управления jar библиотеками, используемыми в проекте.
    Вызвать диалог можно двумя способами:
    Через главное меню: Project -> FGX Android Libraries Через контекстное меню панели Projects. Target Platforms -> Android (32/64 bits) -> Libraries -> Setup Android Libraries.
    Всё, что необходимо для включения в ваше приложение сторонней jar библиотеки — это добавить её в разделе «Все модули» или «Пользовательские».
    Для возврата списка библиотек к первоначальноиу состоянию воспользуйтесь кнопки «По-умолчанию».
  19. Yaroslav Brovin
    Теперь в FGX Native появится новый компонент для отображения рекламы в вашем приложении TfgBannerAd. Компонент позволяет монетизировать ваше приложение и получать пассивный доход.
    Компонент поддерживает несколько видов баннера, поэтому вы всегда сможете подобрать подходящий размер.
    В качестве рекламной площадки используется Google AdMob.
      
    Компонент будет доступен в 1.1.6.0.
  20. Yaroslav Brovin
    В ближайшем релизе 1.1.4.0 появится возможность указывать форматированный текст, используя упрощенный HTML формат.
    Чтобы использовать форматированный текст необходимо:
    1. Указать в свойстве Text HTML разметку.
    Например: 
    <font color='red'>red</font> <b>and</b> <font color='blue'>blue</font> Внимание! Поддерживается только форматирование текста, такое как изменение цвета и стиля текста.
    2. Указать, что нужно воспринимать исходный текст, как HTML разметка (TextType = HTML).

    Внимание! В версии 1.1.4.0 TfgLabel не поддерживает отображение html в дизайнере IDE.

  21. Yaroslav Brovin
    Как вы знаете, библиотека FGX Native - это кроссплатформенная библиотека, разрабатываемая с учетом возможностей добавления новых платформ.
    На текущий момент доступна только платформа Андроид. Однако, работа над iOS уже идет полным ходом.
    Рад поделится с вами промежуточными результатами. Перед вами простое приложение с одной кнопкой и меткой:

    Полностью работает система выравнивания, реализована часть базовых сервисов платформы и сделаны первые наброски стандартных компонентов (кнопки, метки и контейнеры).
    video_2020-04-07_02-12-49.mp4.994174c5afa23d87170f03d57d1b01e0.mp4
  22. Yaroslav Brovin
    В ближайшем релизе FGX Native 1.1.4.0 появится расширение возможностей TfgCollectionView. Речь идет о перетаскивании элементов списка для ручного упорядочивания элементов.
    video_2020-03-27_04-16-58.mp4.01ba77268ea2bcd5c7b56ad7cf398dcc.mp4
    Для того, чтобы воспользоваться новым функционалом нужно:
    1. Определить, за какой компонент элемента можно будет выполнять перетаскивание элемента.
    Например, можно использовать TfgImage с общепринятой иконкой перетаскивания элементов.
    2. Указать для такого компонента стиля имя через LookupName.

    3. Указать в настройках TfgCollectionView имя компонента из пункта (3).

    4. После перетаскивания элементов в списке, отразить изменение последовательности элементов в вашей модели данных в событии OnMovingItem. 
  23. Yaroslav Brovin

    Общая
    Добрый день,
    В ближайшее время выйдет релиз FGX Native 1.13.0.0 с полноценной поддержкой Delphi 11. Обо всех нововведениях по порядку.
    Delphi 11
    Начиная с версии 1.13.0.0 мы включили поддержку Delphi 11. В то же время, мы исключили поддержку 10.3 из инсталлятора на основании результатов голосования:
    Мы переработали все формы дизайнера и добавили полноценную поддержку HiDPI.
    Дизайнер форм
    Добавлен новый режим позволяющий отключать пунктирную рамку компонентов.

    Так же несколько улучшили функцию визуального отображения областей компонентов, добавив отображение областей внутренних отступов бледно зеленым цветов. Это позволяет наглядно и быстро понять, где используются внутренние отступы (TfgControl.Padding).

    Обновления TfgDatePicker и TfgTimePicker
    В этом релизе мы добавили несколько небольших улучшений этих компонентов. Теперь вы можете указать формат ввода времени: 12 или 24 часовой формат. За это отвечает новое свойство TfgTimePicker.Is24HoursMode = (LocaleDependent, True, False). Теперь при старте компонента на платформе Android он по умолчанию выбирает часовой формат на основании текущей локали устройства.
     
    Помимо этого мы добавили режим автоматического расчета размера для этих компонентов AutoSize, который включен по умолчанию. Поэтому, если вам необходимо, чтобы компоненты растягивались по ширине, нужно исключить значение AutoSize.Width.
    Так же, теперь вы можете отдельно указывать задний фон для этих компонентов при помощи свойства BackgroundName.
     
  24. Yaroslav Brovin
    Добрый вечер,
    Мы плотно работаем над новой версией библиотеки FGX Native, в которую войдут новые компоненты-контейнеры и многие другие улучшения. В этой статье мы хотели бы поделиться двумя новыми компонентами-контейнерами TfgVirtualPagerLayout и TfgPagerLayout, которые появятся в релизе 1.13.1.0. 
    TfgVirtualPagerLayout
    Это базовый компонент, который предназначен для динамической загрузки/выгрузки страниц по мере их необходимости. В отличии от привычных подходов с добавлением вложенных компонентов заранее в дизайнере, этот компонент запрашивает загрузку/выгрузку страницы через события OnLoadPage и OnUnloadPage по мере их необходимости. Это значит, что фактически вместо загрузки 10-20 страниц, он загружает только видимую и еще 1-2 смежных в зависимости от текущего состояния компонента и, как следствие, ускоряет загрузку приложения.
    На базе данного компонента можно легко сделать оптимизированный слайдер изображений. Например вот такой:
    PhotoSlider.mp4
    Компонент не хранит все страницы у себя и работает по cхожему c TfgCollectionView принципу, те запрашивает необходимую информацию у разработчика через набор событий. Перед использованием компонента, вам необходимо написать обработчики для 3-х событий:
    OnGetPageCount - вернуть общее количество страниц в компоненте. OnLoadPage - вернуть компонент страницы. Это может быть любой визуальный компонент. Вы можете создавать  страницу в этом событии динамически, а можете реализовать пул объектов, чтобы повторно использовать выгруженные ранее страницы. OnUnloadPage - можно выполнить уничтожение страницы или вернуть страницу в пул объектов для дальнейшего повторного использования. Типичным примером реализации данных событий может быть такой код, создающий страницы с текстом на базе TfgLabel:
    procedure TFormMain.fgVirtualPagerLayout1GetPageCount(Sender: TObject; var ACount: Integer); begin // Сообщаем компоненту о количестве страниц. ACount := 100; end; procedure TFormMain.fgVirtualPagerLayout1LoadPage(Sender: TObject; const AItemIndex: Integer; var APage: TfgControl); var LPage: TfgLabel; begin // Создаем страницу на базе TfgLabel, которая будет отображать номер страницы. LPage := TfgLabel.Create(nil); LPage.Font.Size := 30; LPage.Text := Format('Page %d', [AItemIndex]); APage := LPage; end; procedure TFormMain.fgVirtualPagerLayout1UnloadPage(Sender: TObject; const AItemIndex: Integer; const APage: TfgControl); begin // Удаляем страницу. APage.Free; end; В результате получим:
    Basic_Text_Pages.mp4
     
    Пул страниц
    В этом примере вы можете обратить внимание, что если страницы по структуре одинаковые, то смысла удалять страницу и создавать заново особо не имеет смысла. Поэтому для этого случая, можно написать простой пул объектов, который не будет удалять вкладку, как только она не нужна, а складывать ее в список для дальнейшего повторного использования. Для реализации пула страниц создадим два списка:
    Список используемых страниц в компоненте в текущий момент времени - FAcquiredPages. Список использованных страниц, которые уже не используются в текущий момент времени - FReleasedPages. Код по объявлению списков выглядит так:
    type TFormMain = class(TfgForm) private FAcquiredPages: TList<TfgLabel>; FReleasedPages: TObjsetList<TfgLabel>; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; var FormMain: TFormMain; implementation {$R *.xfm} uses System.SysUtils, FGX.Application, FGX.Dialogs, FGX.Log; { TFormMain } constructor TFormMain.Create(AOwner: TComponent); begin inherited; FAcquiredPages := TList<TfgLabel>.Create; FReleasedPages := TObjsetList<TfgLabel>.Create; end; destructor TFormMain.Destroy; begin FreeAndNil(FAcquiredPages); FreeAndNil(FReleasedPages); inherited; end; Теперь, когда компонент запрашивает страницу мы выполняем простые действия:
    Если страница есть в пуле, то мы ее извлекаем. Если свободной страницы в пуле нет, то создаем новую. Когда же страница выгружается компонентом, мы просто возвращаем ее в пул.
    procedure TFormMain.fgVirtualPagerLayout1GetPageCount(Sender: TObject; var ACount: Integer); begin ACount := 100; end; procedure TFormMain.fgVirtualPagerLayout1LoadPage(Sender: TObject; const AItemIndex: Integer; var APage: TfgControl); var Page: TfgLabel; begin if FReleasedPages.Count = 0 then begin // В пуле нету свободных страниц, создаем новую Page := TfgLabel.Create(nil); Page.Font.Size := 30; end else // В пуле есть свободная страница, берем ее Page := FReleasedPages.ExtractAt(0); // Переносим страницу в список используемых страниц. FAcquiredPages.Add(Page); // Задаем текст и возвращаем страницу Page.Text := Format('Page %d', [AItemIndex]); APage := Page; end; procedure TFormMain.fgVirtualPagerLayout1UnloadPage(Sender: TObject; const AItemIndex: Integer; const APage: TfgControl); begin TfgAssert.IsClass(APage, TfgLabel); // Возвращаем страницу в пул для повторного использования FAcquiredPages.Remove(APage as TfgLabel); FReleasedPages.Add(APage as TfgLabel); end; Теперь мы получили такое же приложение, как и без использования пула, но теперь страницы не пересоздаются по мере их пролистывания, а повторно используются. Тем самым мы ускоряем процедуру загрузки страниц. 
    Таким образом, этот компонент позволяет ускорить загрузку приложения за счет загрузки только необходимых страниц, а не всех сразу. На базе данного компонента можно легко реализовать слайдер изображение с большим количеством изображений и многое другое.
    Динамическое изменение страниц
    Поскольку компонент запрашивает страницы и их количество у разработчика, то при любом изменении количества страниц, удаление/добавление страниц необходимо уведомить об этом компонент при помощи следующих методов:
    Reload - Уведомляет компонент о том, что список страниц изменился и надо заново его построить. NotifyPageInserted - Уведомляет компонент, что в список вставлены новые страницы по указанным индексам. NotifyPageRemoved - Уведомляет компонент, что из списка нужно удалить страницы по указанным индексам. Состав страниц нельзя менять в процессе переключения вкладок!
    Дополнительные события
    Данный компонент предлагает широкий набор дополнительных событий, позволяющих полностью контролировать процесс смены вкладок:
    OnChanged - Вызывается только при интерактивной смене вкладки, как только компонент понимает на какую вкладку окончательно переключается пользователь.  OnBeginDragging - Вызывается, когда пользователь опустил палец на экран и начал двигать содержимое.  OnEndDragging - Вызывается, когда пользователь поднял палец с экрана и закончил двигать содержимое. OnBeginScrolingAnimation - Вызывается, когда началась анимация смены вкладки. OnEndScrolingAnimation - Вызывается, когда анимация смены вкладки закончилась. TfgPagerLayout 
    Этот компонент-контейнер построен на базе TfgVirtualPagerLayout и в отличии от TfgVirtualPagerLayout выравнивает все добавленные в него компоненты по страницам. Он не выгружает/загружает страницы и по сути является аналогом TfgPageControl. Вы добавляете в него любые компоненты и TfgPagerLayout сам осуществляет их выравнивание и переключение.
     
×
×
  • Create New...