Привет, на связи команда Flutter-разработчиков Surf. Мы регулярно делимся с сообществом последними новостями о Dart и Flutter, и этот случай — не исключение. Предлагаем перевод официального материала о большом обновлении Flutter 3.16. Дополнили его своими комментариями.

Добро пожаловать в новый квартал и анонс новой стабильной версии — Flutter 3.16. В этом релизе Material 3 стал темой по умолчанию, открылось превью движка Impeller на Android, и появилась возможность добавлять расширения к DevTools! Так совпало, что одновременно с новым релизом внесли существенные дополнения в Casual Games Toolkit для Flutter.

© Kevin Chisholm, Technical Program Manager for Dart and Flutter, Google.

Всего за три месяца с прошлого релиза мы смёрджили 928 пулл-реквестов от 145 членов сообщества, при этом для 40 из них это был первый коммит во Flutter!

Давайте подробнее рассмотрим все новинки и улучшения, вошедшие в новый релиз Flutter благодаря сообществу.

Мигрировать на новую версию Flutter с каждым обновлением становится всё легче. Мы всё меньше и меньше получаем обновления, которые каким-то серьёзным образом могут влиять на то, как именно мы пишем на Flutter. Это показывает, что Flutter уже стал настолько взрослой технологией, что сейчас мы получаем в основном три типа обновлений: UI-kit в библиотеках, поддержка альтернативных платформ и оптимизация бэкенда. Не думаю, что условный Flutter 4 будет настолько же «ломающим», как Flutter 2 в своё время — и это здорово!

© Марк Абраменко, Flutter Engineering Manager, Surf.

Фреймворк

Material 3 — новая тема по умолчанию

Начиная с версии 3.10 (май 2023) мы вносили изменения в библиотеку Material в соответствии с актуальными спецификациями Material Design. Изменения коснулись новых компонентов и тем компонентов, а также их внешнего вида. До релиза 3.16, эти изменения были опциональными. Начиная с текущей версии, значение useMaterial3 = true по умолчанию. (#130764)

Отказаться от работы с версией M3 библиотеки Material всё ещё можно: для этого нужно указать useMaterial3: false в теме MaterialApp. Тем не менее, однажды Material 2 получит статус «deprecated», и мы его удалим.

Помимо этого, некоторые виджеты было недостаточно просто обновить — им требовалась абсолютно новая реализация. Поэтому UI приложения может выглядеть немного странно после перехода на Material 3. Решение проблемы — мигрировать на новые виджеты (например, NavigationBar) вручную. Подробности вы найдёте в статье о миграции на Material 3 на GitHub.

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

За внешний вид компонентов Material 3 в первую очередь отвечают значения [ThemeData.colorScheme] и [ThemeData.textTheme]. Советуем создавать цветовую схему Material 3 с помощью ColorScheme.fromSeed(). Таким образом и тёмные, и светлые темы будут одновременно красивыми и достаточно контрастными в режиме специальных возможностей. Также цветовые схемы можно создавать на основе цветов, преобладающих на изображении, с ColorScheme.fromImageProvider. Если нужно кастомизировать внешний вид компонентов Material 3 ещё больше, добавьте темы компонентов в ThemeData своего проекта, например ThemeData.segmentedButtonTheme или ThemeData.snackBarTheme. Не null свойства темы компонента переопределяют свойства по умолчанию, указанные в документации API компонента.

Поддержка Material 3 motion

Material 3 motion мы дополнили новыми классами: Easing и Durations. К названиям кривых в Material 2 добавилось слово «legacy». В конечном счёте они получат статус «deprecated» и будут удалены. (#129942)

Дополнительные опции в меню редактирования

На нативном iOS, стала доступна возможность выделять текст и запускать меню «share» с рядом стандартных возможностей. В этом релизе мы добавили опции «look up», «search» и «share».

Масштабирование текста с TextScaler

В помощь людям со слабым зрением на Android 14 вышла новая фича — нелинейное масштабирование шрифта. Чтобы добавить поддержку фичи, мы заменили свойство Text.textScaleFactor классом TextScaler. (#128522)

Обновление SelectionArea

В обновленной версии Flutter SelectionArea поддерживает нативные жесты, привязанные к однократному и двойному клику мыши, а также долгому нажатию на тачскрине. Новые жесты доступны по умолчанию в SelectionArea и SelectableRegion.

  • Однократный клик: устанавливает курсор в выбранной точке.

  • Двойной клик: выделяет слово, по которому кликнули.

  • Двойной клик + перетаскивание: расширяет выделенную область пословно.

  • Долгое нажатие + перетаскивание: расширяет выделенную область пословно.

Контекстные меню виджета в фокусе

В этом релизе мы навели порядок в смене фокуса при работе с меню: функция applyFocusChangesIfNeeded в FocusManager теперь возвращает фокус с меню — пользователь кликает на пункт контекстного меню и фокус тут же возвращается на объект, который был в фокусе до появления меню. (#130536)

Автоматическое упорядочивание клавиш-модификаторов в пунктах меню iOS и macOS

Flutter-приложения на платформах Mac теперь упорядочивают клавиши-модификаторы в меню в соответствии с правилами Apple Human Interface. (#129309)

До
До
После
После

Анимация MatrixTransition

Новый виджет MatrixTransition позволяет создавать анимированные переходы с использованием преобразований. С учётом текущих параметров анимации, можно ввести матрицу преобразований, которая затем применится к дочернему виджету. Таким образом можно создавать эффекты как в примере из DartPad (#131084)

PaintPattern добавлен во flutter_test

В пакете flutter_test добавился класс PaintPattern, с помощью которого можно проверять вызовы метода paint на canvas от виджетов вроде CustomPainter и Decoration (используются в unit-тестах).

Чтобы подтвердить, что программа нарисовала правильный цвет и rect, раньше требовался golden-тест, а теперь вместо него можно использовать PaintPattern. В следующем примере программа проверяет, действительно ли виджет MyWidget нарисовал круг на canvas:

expect(
 find.byType(MyWidget),
 paints
   ..circle(
     x: 10,
     y: 10,
     radius: 20,
     color: const Color(0xFFF44336),
   ),
);
// Можно даже объединить в цепочку несколько вызовов paint.
expect(
 find.byType(MyWidget),
 paints
   ..circle(
     x: 10,
     y: 10,
     radius: 20,
     color: const Color(0xFFF44336),
   ),
   ..image(
     image: MyImage,
     x: 20,
     y: 20,
   ),
);

Раньше этот API сидел глубоко в тестовых файлах фреймворка. Мы заметили, что он приглянулся некоторым разработчикам: они копировали API в свои собственные проекты. Если вы тоже так делали, можете удалять копию из своего проекта, как только обновитесь до Flutter 3.16.

Обновления скроллинга

Первоначальный релиз основы для двухмерного скроллинга состоялся с выходом версии Flutter 3.13. В этом релизе мы добавили больше фич и доработок. Во Flutter 3.16 двухмерная основа стала поддерживать виджеты KeepAlive, а также перемещение фокуса по умолчанию и неявный скроллинг. 2D виджеты скроллинга, собранные поверх основы, станут поддерживать их автоматически. Исчерпывающее руководство по сборке на двухмерной основе вы найдёте в свежем эпизоде Flutter Build Show.

Вскоре после выхода версии 3.13, мы опубликовали пакет two_dimensional_scrollables. Он всё так же поддерживается командой Flutter и включает в себя несколько самых первых виджетов 2D скроллинга, собранных на основе из фреймворка — TableView. Также в этот раз мы добавили поддержку большего числа элементов для оформления и стилизации, а также пофиксили несколько багов.

Движок

Android

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

На графике показаны улучшения, достигнутые за год в 99-м, 90-м и среднем процентилях времени кадра по результатам бенчмарк-тестов производительности анимаций во Flutter Gallery с использованием бэкенда Vulkan. На пользовательской стороне это означает меньше лагов и более высокую стабильную частоту кадров. К концу указанного периода мы перешли с устройств Samsung S10 на Pixel 7 Pro, что объясняет существенный спад показателей. Тем не менее, нам кажется, что общая закономерность и результаты в целом крайне воодушевляющие.
На графике показаны улучшения, достигнутые за год в 99-м, 90-м и среднем процентилях времени кадра по результатам бенчмарк-тестов производительности анимаций во Flutter Gallery с использованием бэкенда Vulkan. На пользовательской стороне это означает меньше лагов и более высокую стабильную частоту кадров. К концу указанного периода мы перешли с устройств Samsung S10 на Pixel 7 Pro, что объясняет существенный спад показателей. Тем не менее, нам кажется, что общая закономерность и результаты в целом крайне воодушевляющие.

Ждать отличной работы Impeller на устройствах без совместимости с Vulkan пока не стоит. В ближайшие месяцы мы планируем доработать фичи OpenGL бэкенда для Impeller к следующему стабильному релизу и параллельно собрать обратную связь о работе Impeller на таких устройствах.

У Flutter разработчиков уже есть возможность опробовать Impeller на Android-устройствах, совместимых с Vulkan. Сделать это можно, передав флаг — enable-impeller во flutter run или добавив код ниже в файл AndroidManifest.xml своего проекта под тэгом <application>:

<meta-data
 android:name="io.flutter.embedding.android.EnableImpeller"
 android:value="true" />

Как Impeller понимает, совместимо устройство с Vulkan или нет? С помощью теста, описанного в документации репозитория Impeller. В целом, Impeller работает с Vulkan на устройствах с 64-битной ОС с Android API 29 уровня или новее. Также можно определить, совместимо ли ваше устройство с Vulkan, с помощью статьи «Проверяем совместимость с Vulkan».

Мы довольны текущим прогрессом в разработке бэкенда Vulkan, но знаем, что в превью есть несколько недочётов:

  • Мы пока не реализовали platform view, поэтому кадры, в которых должны быть platform view, отображаются не очень хорошо.

  • Кастомные шейдеры пока не реализованы.

  • Самый актуальный полный перечень известных нам недочётов и недостающих фич есть в таблице проекта Impeller на GitHub. Многое мы уже отлаживаем и выпустим в бета-версии 3.17, так что загляните и туда тоже.

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

Кроме того, в тестовых сборках бэкенд Vulkan для Impeller подключает дополнительные инструменты отладки, которые не используются со Skia. Дополнительные инструменты Vulkan замедляют программу ещё сильнее. Поэтому отчёты о производительности Impeller очень важно отправлять из релизной сборки или сборки со включённым профилем, а также прилагать хронологию из DevTools и сравнение со Skia на том же устройстве.

Производительность, верность передачи информации и стабильность Impeller

Помимо работы над бэкендом Vulkan, с начала года наша команда внесла ряд улучшений производительности при работе Impeller с текстом как на Android, так и на iOS. В частности, мы усовершенствовали работу с атласом символов Impeller и процесс распределения текстов между растровым и UI потоками движка. В результате пользователи реже будут сталкиваться с лагами при работе с большими объёмами текста.

На графике показан спад значений в 99-м, 90-м и среднем процентилях времени кадра в миллисекундах по результатам одного из наших бенчмарк-тестов с большим объёмом текста на iPhone 11 с Impeller. В частности, 90-й и средний процентиль времени кадра сократились почти вполовину.
На графике показан спад значений в 99-м, 90-м и среднем процентилях времени кадра в миллисекундах по результатам одного из наших бенчмарк-тестов с большим объёмом текста на iPhone 11 с Impeller. В частности, 90-й и средний процентиль времени кадра сократились почти вполовину.

Кроме того, наша команда усиленно работала над улучшением верности передачи информации и стабильности работы как на Android, так и на iOS, уделяя особое внимание недочётам, о которых сообщали пользователи. В частности, за три месяца релизного цикла разработчики закоммитили в репозитории flutter и Impeller 209 изменений. Таким образом, мы отладили 217 багов, включая баги, упомянутые в 42 отчётах пользователей о проблемах с верностью передачи информации, стабильностью и производительностью.

Производительность движка

Чтобы помочь движку работать с большей производительностью на мобильных устройствах с гетерогенной многопроцессорной обработкой данных, мы модифицировали его таким образом, чтобы потоки, сильнее всего снижающие производительность, например UI- и растровый потоки, привязывались к более мощным ядрам устройства. По полученным нами данным, изменение положительно сказалось на производительности в целом ряде бенчмарк-тестов на множестве устройств. В некоторых случаях наблюдались кардинальные улучшения: в 99-м или 90-м процентиле время кадра сокращалось вполовину или сильнее.

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

На графике показаны улучшения показателей в худшем случае, 99-м, 90-м и среднем процентилях времени сборки и растеризации кадра почти во всех бенчмарк-тестах для Android и почти на всех Android-устройствах.
На графике показаны улучшения показателей в худшем случае, 99-м, 90-м и среднем процентилях времени сборки и растеризации кадра почти во всех бенчмарк-тестах для Android и почти на всех Android-устройствах.

Улучшения API и верности передачи данных

Оверлей производительности Impeller

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

Дизеринг отображается корректно

В этом релизе свойство Paint.enableDithering = true, и получило статус «deprecated» согласно с политикой депрекации Flutter. Дизеринг теперь работает по умолчанию (настроить дизеринг разработчики не смогут), а с изображений пропадёт бандинг. Подробную информацию об изменении, а также гайд по миграции вы можете найти на странице изменений без обратной совместимости на docs.flutter.dev.

До
До
После
После

Игры

Flutter Games Toolkit

За последние несколько лет сообщество разработчиков казуальных игр заметно выросло. На сегодняшний день опубликованы десятки тысяч игр на Flutter, от структурно простых, но занимательных головоломок до более сложно устроенных аркадных игр.

Среди наших любимчиков — Trivia Crack от Etermax, 4 Pics 1 Word (словесная головоломка) от Lotum, Brick Mania (аркадная игра) от Dong Digital, StopotS (игра в категории) от Onrizon, ретро пинбол, который мы написали к Flutter I/O, и PUBG MOBILE, где на Flutter написаны экран меню и экраны для общения игроков друг с другом.

В качестве подспорья для разработчиков мы выпускаем масштабное обновление Casual Games Toolkit для Flutter. В нём собраны новые ресурсы, которые помогут пройти путь от концепта до релиза: больше шаблонов для конкретных жанров (карточные игры, платформеры в жанре «endless runner»), а также интеграции с такими сервисами, как Play Games Services, покупки в приложении, реклама, цели и достижения, crashlytics и поддержка многопользовательских игр. Подробнее об этом можно почитать в посте о запуске тулкита для игр от Зоуи Фэн.

Как ни странно, компания Google больше всех трудится над актуализацией и внедрением новых материалов именно для этого тулкита (помянем шаблон для разработки новостных приложений). Количество новых игр все больше поражает, как и растущее желание студий сменить свои текущие решения на Flutter.

В дополнение ко всему, команда игрового движка Flame обновила
свой сайт и анонсировала новый конкурс по разработке игр «Flame Game Jam 3.0», где разработчики из команды Surf планируют принять участие. Увидимся на джеме!

© Артур Шамсутдинов, Middle Flutter Developer, Surf.

Веб

Timeline events Flutter-приложений в Chrome DevTools

Timeline events во Flutter теперь отображаются на панели производительности в Chrome DevTools. (#130132)

Подробнее об этом можно почитать в статье «Отладка производительности в веб-приложениях».

Android

Поддержка колёсика мыши

Мы приводили Wonderous в соответствие с рекомендациями для Android-устройств с большим экраном и помимо прочего обнаружили, что на планшетах и складных устройствах колёсико мыши работало плохо. Не секрет, что на прокрутку колёсиком экран реагировал совсем не сразу.

В этом релизе скорость скроллинга мышью во flutter view аналогична скорости на Android-устройствах. (44724)

До
До
После
После

Predictive back navigation

В версию Android 14 вошла фича «predictive back gesture», с помощью которой жестом «назад» можно сдвинуть в сторону текущий экран и посмотреть на часть рабочего стола телефона за ним. В новой версии Flutter тоже поддерживает эту фичу! Подробнее в гайде по миграции.

iOS

Расширения приложений

Теперь Flutter можно использовать для некоторых расширений iOS-приложений. Другими словами, вы можете нарисовать UI для определённых видов расширений к iOS-приложениям с помощью виджетов Flutter. Такая возможность доступна не для всех типов расширений, так как у API (к примеру у виджетов рабочего стола) или памяти иногда бывают определённые ограничения.

Почитать подробнее и посмотреть пример работы с расширением Share можно в статье «Как добавить расширения к iOS-приложениям» на docs.flutter.dev.

Пакетная экосистема

Обновлённые Flutter Favorites

Мы перезапустили программу Flutter Favorite! В этот раз комитет экосистемы Flutter внёс в избранное пакеты flame, flutter_animate, flutter_rust_bridge, riverpod, video_player, macos_ui и fpdart. Поздравляем вас!

Продолжайте следить за новинками во Flutter Favorites. Если хотите номинировать пакет или плагин на место во Flutter Favorites, обратить внимание комитета на любой другой вопрос, отправьте комитету письмо на flutter-committee@googlegroups.com.

Первый виртуальный саммит по пакетной экосистеме

Этим августом мы провели первый виртуальный саммит по пакетной экосистеме, участие в котором приняли более 50 контрибьюторов в pub.dev: как из Google, так и извне. Целью было познакомить разработчиков друг с другом и организовать не классические для конференций обсуждения, в процессе которых члены сообщества смогут строить планы, делиться знаниями и учиться друг у друга. После мы провели опрос и выяснили, что участники были на 100% довольны саммитом.

Мы планируем и дальше проводить похожие встречи на тему пакетной экосистемы и взаимодействовать с сообществом (виртуально и оффлайн). Подробности можно будет узнать в нашем блоге (в уже запланированном посте об обновлениях пакетной экосистемы).

Форматирование Google Maps в облачной консоли

Платформа Google Maps позволяет кастомизировать карту по одному из шаблонов форматирования на странице Map Styles в Google Cloud Console. С их помощью можно подстроить карты под своё приложение, при этом не обновляя код с каждым новым форматированием.

Воспользоваться фичей во Flutter просто: нужно сослаться на свою карту в Map ID консоли:

GoogleMap(
       onMapCreated: _onMapCreated,
       initialCameraPosition: const CameraPosition(
         target: _kMapCenter,
         zoom: 7.0,
       ),
       key: _key,
       cloudMapId: _mapId
);

Улучшенная Camera X

В стабильной версии 3.10 мы добавили пробную поддержку Camera X в плагин камеры Flutter. Camera X — это Jetpack библиотека, которая помогает легко добавить более сложные фичи камеры в Android-приложение.

В этом релизе мы добавили большинство фич, необходимых почти любому приложению, которое взаимодействует с камерой. CameraX решает множество проблем плагина Camera 2.

Настоятельно рекомендуем использовать плагин CameraX. Просто добавьте следующие строки в файл pubspec.yaml своего проекта — готово!

Dependencies:
camera: ^0.10.4 # Или последняя версия камеры
camera_android_camerax: ^0.5.0

Видеоплеер на macOS

Мы добавили поддержку macOS в плагин видеоплеера: теперь проигрывать видео можно на поверхности виджета.

Подробности можно почитать в статье о плагине видеоплеера на pub.dev.

Очень здорово, что сообщество и команда Flutter всё больше обращают внимание на десктопные платформы. MacOS уже сейчас работает на Flutter очень хорошо. Добиться UI уровня нативных инструментов уже очень и очень просто. Чуть выше можно было увидеть, что в «Favorites» был добавлен UI-kit для macOS. Самое ожидаемое обновление для Flutter прямо сейчас — работа с окнами на десктопных платформах. Ждём!

© Марк Абраменко, Flutter Engineering Manager, Surf.

DevTools

Расширения DevTools

Новый фреймворк расширений для DevTools позволяет:

  • авторам пакетов собрать тулкит специально под свой пакет и после сохранить его в DevTools.

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

  • Dart- и Flutter-разработчикам, занимающимся отладкой приложений в DevTools, получить доступ к инструментам, созданным для их конкретного юзкейса (зависит от зависимостей в приложении и наличия у них расширений DevTools).

Благодаря создателям пакетов Provider, Drift и Patrol, экосистема уже разрастается. Для этих пакетов можно пользоваться расширениями DevTools прямо сейчас!

Provider
Drift
Patrol

Подробнее о расширениях DevTools можно почитать в анонсе расширений DevTools для Dart и Flutter от Кензи Дейвиссон.

Дополнения к DevTools

Несколько ключевых дополнений к DevTools из этого релиза:

  • Добавили поддержку расширений DevTools

  • Добавили новый «Главный экран», где показаны обобщённые сведения о подключенном приложении.

Помимо прочего, улучшили:

  • Производительность в целом

  • Робастность hot restart

  • Поведение при выборе и копировании текста

  • И доработали отображения откликов в Network profiler

Подробнее об этом в примечаниях к DevTools 2.26.1, 2.27.0 и 2.28.1.

Интуитивный UI в VS Code

Благодаря потрясающему вкладу разработчика DanTup из Flutter-сообщества, у расширения Flutter VS Code теперь есть Flutter Sidebar, который предоставляет лёгкий доступ к:

  • Открытым экранам Flutter DevTools

  • Просмотру активных сессий отладки

  • Просмотру доступных устройств

  • Созданию новых проектов

  • Hot reload и restart

  • Запуску Flutter Doctor -v

  • И многому другому

Deprecated элементы и изменения без обратной совместимости

В этом релизе такие изменения включают deprecated API, потерявшие актуальность после релиза v3.13. Список всех API, а также дополнительный контекст и гайд по миграции вы найдёте в гайде по deprecated элементам в этом релизе. Многие из них поддерживаются Flutter fix, включая quick фиксы в IDE. Все фиксы разом можно оценить и применить с помощью команды dart fix.

И как всегда, огромное спасибо сообществу за ваши тесты — с их помощью мы находим изменения без обратной совместимости. Подробную информацию вы найдёте в Политике Flutter по изменениям без обратной совместимости.

В следующем релизе мы планируем распространить политику депрекации на пакет flutter_driver, а также на уже поддерживаемые пакеты flutter и flutter_test.

Заключение

Мы указали точное количество контрибьюторов в самом начале анонса и сделали это специально. Flutter никогда бы не стал настолько же приятным и полезным тулкитом без вас, нашего потрясающего сообщества! Спасибо.

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

С сегодняшнего дня доступ к Flutter 3.16 в стабильном канале открыт и включает Dart 3.2. Попробовать обновления легко: просто введите flutter upgrade. До скорых встреч!

Больше полезного про Flutter — в Telegram-канале Surf Flutter Team. Кейсы, лучшие практики, новости и вакансии в команду Flutter Surf в одном месте. Присоединяйтесь.

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