Улучшенная поддержка Material 3, обновления DevTools, новые виджеты – Google представил очередное обновление кроссплатформенного фреймворка.

По традиции, команда Flutter-разработчиков Friflex делится первым переводом официального релиза новой версии фреймворка с комментариями.

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

Давайте вместе отправимся в небольшое путешествие, чтобы изучить новые функции Flutter 3.7!

Улучшенная поддержка Material 3

Поддержка Material 3 была значительно расширена в версии 3.7 за счет переноса следующих виджетов:

Чтобы использовать эти новые функции, просто включите флаг useMaterial3 в виджете ThemeData вашего приложения. Чтобы в полной мере воспользоваться поддержкой M3, вам понадобится полная цветовая схема M3. Вы можете предоставить свою собственную с помощью нового инструмента генерации тем, или Flutter может сгенерировать ее за вас из одного исходного цвета, используя параметр colorSchemeSeed в конструкторе ThemeData:

MaterialApp(
 theme: ThemeData(
    useMaterial3: true,
   colorSchemeSeed: Colors.green,
 ),
 // …
);

Подробнее о поддержке Flutter Material 3 смотрите в выпуске umbrella на GitHub.
Чтобы самостоятельно поиграть с этими компонентами, посмотрите интерактивное демо, показывающее все новые функции M3:

Строки меню и каскадные меню

Flutter теперь может создавать строки меню и каскадные контекстные меню.

Для macOS создайте строку меню с помощью виджета PlatformMenuBar, который определяет собственные строки меню платформы, которые рендерит macOS, а не Flutter.

И для всех платформ вы можете определить меню Material Design, которое предоставляет каскадные строки меню (MenuBar) или автономные каскадные меню, запускаемые другим элементом пользовательского интерфейса (MenuAnchor). Эти меню полностью настраиваемые, а пункты меню могут быть пользовательскими виджетами, или вы можете использовать новые виджеты пунктов меню (MenuItemButton, SubmenuButton).

Предпросмотр Impeller

Новый движок рендеринга Impeller готов для предварительного просмотра на iOS на стабильном канале. Команда считает, что производительность Impeller будет соответствовать или превосходить рендер Skia для большинства приложений, а что касается точности, то Impeller реализует все, кроме небольшого числа редко используемых крайних случаев. Планируется сделать Impeller средством рендеринга по умолчанию на iOS в предстоящем  релизе, отзывы об Impeller можно оставлять на GitHub.

Вероятно,  Impeller на iOS удовлетворит потребности в рендеринге почти всех существующих приложений Flutter, но все еще есть несколько пробелов в охвате API. Небольшое количество оставшихся пробелов указано на вики Flutter. Пользователи также могут заметить небольшие визуальные различия в рендеринге между Skia и Impeller. Эти незначительные различия могут быть ошибками.

Продолжается работа над серверной частью Vulkan для Impeller (с откатом к OpenGL на старых устройствах), но Impeller для Android еще не готов для предварительного просмотра. Поддержка Android находится в стадии активной разработки.

За прогрессом можно следить на доске проекта Impeller на GitHub.

Проверка релиза iOS

Когда вы выпускаете приложение для iOS, чеклист параметров для обновления гарантирует, что ваше приложение готово к отправке в App Store.

Команда flutter build ipa теперь проверяет некоторые из этих настроек и сообщает, есть ли изменения, которые необходимо внести в ваше приложение перед релизом.

Обновления DevTools 

«В обновлении добавились новые типы отладки. Теперь можно сравнивать потребление памяти, например, до и после внедрения новой функции.  Также появилась новая  интересная новая вкладка Frame Analysis, где можно подробно изучить производительность отдельно выбранного кадра. Это очень нужный инструмент для создания быстрых и высоко нагруженных приложений».

Юрий Петров, Flutter Team Lead, Friflex.

В этом релизе есть несколько новых функций инструментов и общих улучшений, которые можно опробовать. Инструмент отладки памяти DevTools подвергся полной переработке. Есть три новые вкладки функций: Profile (профиль), Trace (трассировка) и Diff (различия), которые поддерживают все ранее поддерживаемые функции отладки памяти и добавлены дополнительные для облегчения отладки. Новые функции включают в себя возможность анализировать текущее выделение памяти для вашего приложения по классам и типам памяти, исследовать, какие пути кода выделяют память для набора классов во время выполнения, и сравнивать снимки памяти, чтобы понять управление памятью между двумя моментами времени.

Все эти новые функции памяти были описаны на docs.flutter.dev.

На странице Performance (производительность) также есть несколько примечательных новых функций. Новая вкладка Frame Analysis (анализ кадров) в верхней части страницы производительности предоставляет информацию для выбранного кадра Flutter. Инсайты могут включать в себя предложения о том, как более подробно отслеживать дорогостоящие части фрейма Flutter, или предупреждения о дорогостоящих операциях, обнаруженных в фрейме Flutter.

Это всего лишь пара основных моментов, но этот релиз содержит несколько исправлений ошибок и улучшений кроме упомянутых функций, в том числе некоторые важные исправления ошибок для Inspector, профилировщика сети и профилировщика ЦП. Чтобы получить более подробный список обновлений, ознакомьтесь с примечаниями к релизу изменений DevTools, которые вошли во Flutter 3.7.

Пользовательские контекстные меню

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

Например, вы можете добавить кнопку «Отправить e-mail» на панель инструментов выбора текста по умолчанию, которая появляется, когда пользователь выбирает адрес электронной почты (код). См. параметр contextMenuBuilder, который был добавлен к существующим виджетам, отображающим контекстное меню по умолчанию, например TextField. Вы можете вернуть любой виджет  из contextMenuBuilder, включая изменение контекстного меню, адаптированного к платформе по умолчанию.

Эта новая функция работает и за пределами выделения текста. Например, вы можете создать виджет Image, который показывает кнопку «Сохранить» при щелчке правой кнопкой мыши или длительном нажатии (код). Используйте ContextMenuController для отображения контекстного меню текущей платформы по умолчанию или пользовательского меню в любом месте вашего приложения.

См. полный набор примеров в репозитории примеров Flutter.

Виджеты CupertinoListSection и CupertinoListTile

В Cupertino есть два новых виджета, CupertinoListSection и CupertinoListTile, для отображения прокручиваемого списка виджетов в стиле iOS. Они являются альтернативами Cupertino для ListView и ListTile в Material.

Улучшения прокрутки

С новым релизом появилось несколько обновлений прокрутки: полировка и усовершенствование взаимодействия с трекпадом, новые виджеты, такие как Scrollbars и DraggableScrollableSheet, а также улучшенная обработка выделения текста в контекстах прокрутки.

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

Новые виджеты AnimatedGrid и SliverAnimatedGrid анимируют элементы, добавленные в список (или удаленные из него).

В заключение, была исправлена регрессия в конструкторе builder нескольких виджетов прокрутки, таких как ListView. Во время миграции NNBD платформы Flutter itemBuilder, который позволяет пользователям предоставлять виджеты по запросу, был перенесен в IndexedWidgetBuilder. Это означало, что itemBuilder больше не мог возвращать значение null, которое (в прошлом) можно было использовать для обозначения достижения конца списка. Эта функциональность была восстановлена с помощью NullableIndexedWidgetBuilder. 

Инструменты и документы интернационализации

Поддержка интернационализации была полностью переработана, переписан инструмент gen-l10n, и теперь он поддерживает:

  • Описательные синтаксические ошибки.

  • Сложные сообщения, включающие вложенные/множественные формы множественного числа, выборки и заполнители.

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

Улучшения глобального выбора

SelectionArea теперь поддерживает выбор клавиатуры. Вы можете расширить существующий выбор с помощью сочетаний клавиш, таких как shift+right.
Видео пример новых улучшений глобального выбора

Фоновые изоляты

«С помощью данного обновления теперь можно использовать platform channels в отдельном изоляте. Соответственно, так же можно запускать и плагины. Например, вы можете запустить плагин shared_preferense в отдельном изоляте и исключить влияние на главный изолят при большом сохранении данных».

Юрий Петров, Flutter Team Lead, Friflex.

Теперь каналы платформы можно вызывать из любого Isolate. Раньше пользователи могли вызывать каналы платформы только из основного изолята Flutter. Это упрощает работу с изолятами и кодом хост-платформы в плагинах или дополнениях к приложению. Для получения дополнительной информации можно ознакомиться с разделом «Написание пользовательского кода для конкретной платформы» на сайте flutter.dev и подробной статьей «Введение в каналы фоновой изоляции» — бесплатной статьей на Medium.

Текстовая лупа

Текстовая лупа, появляющееся при выделении текста на Android и iOS, теперь работает во Flutter. Это включено по умолчанию для всех приложений с выделением текста, но если вы хотите отключить или настроить его, см. свойство magnifierConfiguration.

Быстрая миграция для плагинов

Поскольку Apple сосредоточилась на Swift для своих собственных API, мы хотели разработать ссылки, чтобы помочь разработчикам плагинов Flutter мигрировать или создавать новые плагины с помощью Swift. Плагин quick_actions был перенесен с Objective-C на Swift и может использоваться в качестве демонстрации. Если вы заинтересованы в том, чтобы помочь нам перенести плагины 1P, см. раздел «Миграция Swift» на вики.

Ресурсы для iOS-разработчиков

Опубликовано несколько новых ресурсов для разработчиков iOS, в том числе:

Прекращение поддержки битового кода

Начиная с Xcode 14, биткод больше не требуется для приложений watchOS и tvOS, а App Store больше не принимает биткоды из Xcode 14. Таким образом, поддержка биткода была удалена из Flutter.

По умолчанию в приложениях Flutter не включен биткод, и мы не ожидаем, что это повлияет на многих разработчиков. Однако, если вы включили биткод вручную в своем проекте Xcode, отключите его, как только обновитесь до Xcode 14. Вы можете сделать это, открыв ios/Runner.xcworkspace и установив для параметра «Enable Bitcode» значение «False». Разработчики надстроек должны отключить это в хост-проекте Xcode.

Чтобы узнать больше о распространении биткода, ознакомьтесь с документацией Apple.

Фоновый фильтр для iOS PlatformView 

Добавлена возможность размытия нативных views для iOS при отображении под размытым виджетом Flutter, а виджеты UiKitView теперь можно обернуть внутри BackdropFilter.

Дополнительные сведения см. в документации по дизайну iOS PlatformView BackdropFilter.

Управление памятью

В этом релизе представлено несколько улучшений в управлении памятью, которые в совокупности снижают количество зависаний, вызванных паузами при сборке мусора, снижают загрузку ЦП из-за скорости выделения и фоновых потоков сборки мусора, а также уменьшают объем занимаемой памяти.

Например, мы расширили существующую практику ручного освобождения собственных ресурсов, поддерживающих определенные объекты dart:ui Dart. Раньше собственные ресурсы удерживались движком Flutter до тех пор, пока мусор Dart VM не собирал объекты Dart. Анализируя пользовательские приложения и наши собственные тесты, мы определили, что эта стратегия в целом не позволяет избежать несвоевременных GC и чрезмерно загружает память. Поэтому в этом релизе движок Flutter добавляет API для явного освобождения собственных ресурсов, удерживаемых объектами Vertices, Paragraph и ImageShader.

В тестах разработчиков фреймворка Flutter, перенесенного на этот API, эти улучшения сократили время сборки кадра с 90% до более чем 30%, что конечные пользователи будут воспринимать как более плавную анимацию с меньшим количеством рывков.

Кроме того, движок Flutter больше не регистрирует размер изображений графического процессора с помощью Dart VM. Как указано выше, эти изображения уже были вручную освобождены платформой, когда они больше не нужны, поэтому информирование GC-политики Dart о размере памяти графического процессора, поддерживающего объекты кучи Dart, без необходимости увеличивало нагрузку на память кучи Dart, вызывая несвоевременные GC, которые не могли набрать дополнительную память. Аналогичным образом, теперь политика движка Flutter заключается в том, чтобы сообщать Dart VM только поверхностный размер нативных объектов, которые поддерживают объекты dart:ui Dart.

В наших тестах это изменение устраняет синхронную работу GC при построении кадров, когда виджет создает резидентные изображения GPU.

В этом релизе Flutter Engine также лучше динамически обновляет Dart VM информацией о состоянии приложения Flutter. В частности, Flutter теперь использует API-интерфейс Dart VM в стиле RAIL для перехода в режим с малой задержкой во время анимации перехода маршрута. В этом режиме с малой задержкой распределитель памяти Dart VM предпочитает увеличение кучи, а не сборку мусора, чтобы избежать прерывания анимации перехода паузами для сборки мусора. Хотя это изменение не привело к значительному повышению производительности, мы планируем расширить использование этой модели в будущих релизах, чтобы устранить несвоевременные паузы при сборке мусора. 

Мы также исправили ошибку в логике, которая решает, когда уведомлять Dart VM о том, что движок Flutter простаивает. Исправление этих ошибок также предотвращает дерганье, связанное с сборщиком мусора. Наконец, для приложений Flutter, добавляемых в приложение, механизм Flutter теперь информирует Dart VM, когда Flutter view больше не отображается. Теперь это приводит к тому, что виртуальная машина Dart инициирует финальную основную сборку мусора для Isolate, связанного с view. Это изменение уменьшает занимаемый Flutter объем памяти, когда Flutter view не видны.

Закрытие macOS с 10.11 по 10.13

Как было объявлено ранее, Flutter больше не поддерживает macOS версий 10.11 и 10.12. После этого объявления дальнейший анализ показал, что удаление поддержки 10.13 также ограничило бы дополнительное влияние и помогло бы команде значительно упростить кодовую базу. Это означает, что приложения, созданные для стабильных SDK Flutter в этом релизе и более поздних версиях, больше не будут работать в этих версиях, а минимальная версия macOS, поддерживаемая Flutter, увеличивается до 10.14 Mojave.

Как следствие, поскольку все версии iOS и macOS, поддерживаемые Flutter, включают поддержку Metal, серверная часть OpenGL была удалена из модулей встраивания iOS и macOS. Удаление этих серверных частей уменьшило сжатый размер движка Flutter примерно на 100 КБ.

toImageSync

В этом релизе в dart:ui добавлены методы Picture.toImageSync и Scene.toImageSync, аналогичные асинхронным методам Picture.toImage, и Scene.toImage.Picture.toImageSync синхронно возвращает дескриптор Image из  Picture с растеризацией для Image, которая происходит асинхронно в фоновом режиме. Затем изображение сохраняется как резидентное в графическом процессоре, когда доступен контекст графического процессора, что означает, что его отрисовка выполняется быстрее по сравнению с изображениями, созданными toImage. (Изображения, созданные с помощью toImage, также могут оставаться резидентными в графическом процессоре, но эта оптимизация еще не реализована в этом сценарии.)

Новые API-интерфейсы toImageSync поддерживают такие варианты использования, как:

  • Быстрая обрезка дорогостоящего для растрирования изображения в нескольких кадрах.

  • Применение многопроходных фильтров к изображению.

  • Применение пользовательских шейдеров.

Как пример, фреймворк Flutter теперь использует этот API для повышения производительности переходов между страницами на Android, что почти вдвое сокращает время растеризации кадров, уменьшает рывки и позволяет анимации достигать 90/120 кадров в секунду на устройствах, поддерживающих эту частоту обновления.

Улучшение поддержки пользовательских шейдеров

«Долгожданное обновление API для работы с шейдерами. До этого релиза было немного сложно работать с шейдерами, так как не было встроенного компилятора для GLSL файлов. Теперь ситуация изменилась: встроенный компилятор и удобное API позволяют создавать красивые и уникальные  визуальные эффекты. Я думаю, что совсем скоро мы увидим много красивых интерфейсов, построенных с использованием шейдеров».

Юрий Петров, Flutter Team Lead, Friflex.

Этот релиз включает многочисленные улучшения поддержки Flutter для пользовательских фрагментных шейдеров. Flutter SDK теперь включает компилятор шейдеров, который компилирует шейдеры GLSL, перечисленные в файле pubspec.yaml, в правильный внутренний формат для целевой платформы. Кроме того, пользовательские шейдеры теперь можно перезагружать в режиме hot reload для удобного цикла разработки. Пользовательские шейдеры также теперь поддерживаются бэкендами Skia и Impeller на iOS.

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

https://twitter.com/reNotANumber/status/1599717360096620544

https://twitter.com/reNotANumber/status/1599810391625719810

https://twitter.com/wolfenrain/status/1600242975937687553

https://twitter.com/iamjideguru/status/1598308434608283650

https://twitter.com/rxlabz/status/1609975128758026247

https://twitter.com/RealDevOwl/status/1528357506795421698

https://twitter.com/TakRutvik/status/1601380047599808513

https://twitter.com/wolfenrain/status/1600601043477401606

См. подробную документацию по написанию и использованию пользовательских фрагментных шейдеров на docs.flutter.dev и полезный пакет утилит flutter_shaders на pub.dev.

Hot reload для Font asset

Раньше добавление новых шрифтов в файл pubspec.yaml требовало пересборки приложения для их просмотра, в отличие от других типов ресурсов, которые можно было перезагружать в режиме hot reload. Теперь изменения в манифесте шрифтов, включая добавление новых шрифтов, можно перезагружать в приложение в режиме hot reload.

Снижение рывков анимации на устройствах iOS

Благодаря вкладу с открытым исходным кодом от luckysmg два улучшения уменьшили рывки анимации на iOS. В частности, добавление dummy-варианта CADisplayLink в основной поток во время жестов теперь приводит к обновлению с максимальной частотой обновления. Кроме того, анимация клавиатуры теперь устанавливает частоту обновления  CADisplayLink на ту же частоту обновления, которая используется аниматором движка Flutter. Благодаря этим изменениям пользователи должны заметить более плавную анимацию на устройствах iOS с частотой 120 Гц.

Как вам обновление? Делитесь опытом перехода на Flutter 3.7 в комментариях.

Комментарии (2)


  1. beduin01
    27.01.2023 19:16

    Что со стейтменеджерами? Ничего нового интересного в 2023 году не появилось?


    1. friflex_dev Автор
      30.01.2023 10:26

      В этом релизе ничего нового по стейт менеджерам не было