Вышел Flutter 3.47, и вместе с ним мы подготовили несколько захватывающих обновлений.
Сегодня мы приветствуем выпуск версии 1.0 отдельных пакетов material_ui и cupertino_ui. Это важная веха, которая отделяет системы дизайна от основного SDK.
Мы также повышаем производительность и улучшаем инструменты по всем направлениям. Этот релиз делает Impeller стандартным движком на десктопе, подготавливает наши конвейеры к iOS, macOS и Xcode 27, а также переводит Flutter Widget Previews в статус стабильных.
Запустите flutter upgrade в своем терминале, чтобы начать работу, или читайте дальше, чтобы узнать больше об основных изменениях в этом релизе.
Выберите свое собственное UI-приключение
Первый шаг к разделению Flutter сделан: Material и Cupertino теперь доступны в виде отдельных пакетов!
Одной из главных сильных сторон Flutter является способность отрисовывать пиксельно-идеальные виджеты Material и Cupertino. Однако, поскольку эти библиотеки дизайна исторически были встроены непосредственно в основной SDK, это замедляло их разработку и затрудняло внесение вкладов или поддержание их в актуальном состоянии.
Хотя основной SDK по-прежнему включает эти библиотеки в данном релизе, теперь вы можете подключить отдельные пакеты material_ui и cupertino_ui, которые официально достигли версии 1.0 на pub.dev.
Разделение дорожных карт дизайна (по выбору)
Выбирая раздельные системы дизайна, вы получаете контроль над своей дорожной картой дизайна. Поскольку material_ui и cupertino_ui теперь живут на pub.dev, они могут выпускать исправления ошибок и новые компоненты по собственному еженедельному графику, независимо от квартальных релизов Flutter SDK.
Разделение систем дизайна дает нам следующие преимущества:
- Вы можете использовать новейшие стили виджетов Cupertino и Material, не будучи вынужденными обновлять всю версию Flutter SDK.
- Мы можем внедрять вклады и обновления быстрее и чаще.
- Мы закладываем основу для нейтрального к стилю каталога основных виджетов Flutter, что упростит создание пользовательских систем дизайна в будущем.
Как мигрировать
Чтобы перенести ваш проект на новые отдельные пакеты, выполните следующую команду:
bash
Этот инструмент автоматически обновляет ваши импорты из package:flutter/material.dart и package:flutter/cupertino.dart на новые отдельные пакеты.
Примечание: Если инструмент миграции сталкивается с проблемами при обновлении вашего pubspec.yaml (известная ранняя ошибка), вы можете решить ее, вручную запустив flutter pub add material_ui (и cupertino_ui, если вы его используете), а затем снова запустив dart fix --apply.
Примечание: Если инструмент миграции сталкивается с проблемами при обновлении вашего pubspec.yaml (известная ранняя ошибка), вы можете решить ее, вручную запустив flutter pub add material_ui (и cupertino_ui, если вы его используете), а затем снова запустив dart fix --apply.
Оригинальные библиотеки дизайна внутри основного SDK запланированы к официальному устареванию в предстоящем осеннем стабильном релизе в ноябре. Если вы мигрируете пакет в экосистеме, рассматривайте этот переход на отдельные пакеты как мажорный релиз.
Преодоление разрыва при миграции
Чтобы облегчить переход по мере того, как экосистема мигрирует на новые отдельные библиотеки дизайна, material_ui и cupertino_ui поставляются с утилитами миграции. MaterialUiCompatibilityBridge позволяет вашему приложению немедленно мигрировать на отдельные пакеты, даже если некоторые из ваших зависимостей пакетов все еще используют устаревшие импорты основного SDK.
Например, вы можете обернуть свое приложение в мост совместимости:
dart
Раздельные локализации
В рамках этого перехода flutter_localizations также был отделен. Делегаты локализации и переведенные строки для виджетов Material и Cupertino теперь находятся внутри package:material_ui и package:cupertino_ui соответственно.
До:
dart
После:
dart
Установка localizationsDelegates в GlobalMaterialLocalizations.delegates теперь также включает делегаты Cupertino и Widgets, что упрощает вашу настройку.
Открыто для вкладов
Заморозив вклады в библиотеки Material и Cupertino еще в апреле, мы смогли обеспечить плавную миграцию. Библиотеки, ожидающие вас в material_ui и cupertino_ui, — это те же самые библиотеки, которые вы уже используете.
Теперь, когда мы готовы снять заморозку, ожидайте больше исправлений и функций, которые будут регулярно появляться в новых пакетах, с релизами, запланированными на еженедельную основу. Мы также рады официально открыть эти пакеты для вкладов сообщества.
Подготовка к следующей волне обновлений Apple
Поскольку Xcode 27, iOS 27 и macOS 27 появятся этой осенью, мы сосредоточились на том, чтобы Flutter был готов к предстоящим обновлениям. Чтобы ваши пользователи не столкнулись с сюрпризами в первый же день, мы рекомендуем протестировать ваши приложения с бета-версиями Apple уже сейчас.
Кроме того, для поддержки Xcode 27 были повышены минимальные поддерживаемые версии ОС:
Мандат жизненного цикла UIScene
SDK iOS 27 теперь требует жизненный цикл UIScene для всех приложений на базе UIKit. Приложения, созданные с помощью Xcode 27, которые не используют UIScene, не смогут запуститься при старте.
Для большинства приложений Flutter CLI обрабатывает эту миграцию автоматически во время сборки. Однако ручная миграция требуется, если у вас есть пользовательский нативный код в AppDelegate или вы используете плагины, которые все еще полагаются на устаревший жизненный цикл приложения. В таких случаях вы должны мигрировать вручную, следуя Руководству по внедрению UIScene/Delegate.
Постепенный отказ от Intel Mac
В соответствии с переходом Apple на Apple Silicon, Flutter сворачивает поддержку Mac на базе Intel. Мы отключили автоматические запуски тестов на оборудовании Intel, и Flutter CLI теперь выводит предупреждения при сборке на хостах Intel или при нацеливании на двойные архитектуры. Эти предупреждения станут ошибками в будущих релизах.
Вы можете немедленно перейти на сборку приложений macOS только для ARM64, выполнив flutter config --enable-macos-arm64-only.
Прогресс Swift Package Manager
Сообщество добилось невероятного прогресса в переходе на Swift Package Manager: 92 из 100 лучших iOS-плагинов уже мигрировали. Если вы ранее отключали Swift Package Manager, вы можете попробовать его снова, выполнив flutter config --enable-swift-package-manager.
Поскольку CocoaPods теперь находится в режиме обслуживания, плагины, которые не мигрируют на SwiftPM, со временем перестанут работать. Немигрировавшие плагины также получают более низкие оценки на pub.dev. Если вы поддерживаете плагин, ознакомьтесь с Руководством по миграции и прочитайте наш предыдущий пост в блоге для получения более подробной информации.
Этот релиз также отличается оптимизированным временем сборки благодаря участнику сообщества @lukemmtt, который улучшил конвейеры сборки, отфильтровывая ненужные схемы пакетов SwiftPM на ранних этапах процесса сборки (#186006).
Курс на Wasm по умолчанию
Мы активно работаем над тем, чтобы сделать WebAssembly (Wasm) стандартом для веб-приложений Flutter, обеспечивая производительность, близкую к нативной, в браузере. Если вы еще не тестировали свои веб-приложения с Wasm, вы можете включить его сегодня, передав флаг --wasm в команду сборки релиза:
bash
При подготовке к этому переходу помните, что Wasm требует миграции вашей кодовой базы на новый пакет JS interop (package:web), так как устаревшая библиотека dart:html не поддерживается. Обновление зависимостей пакетов вашего проекта часто автоматически решает эти проблемы устаревшего взаимодействия.
Чтобы помочь в масштабировании крупных веб-приложений, этот релиз также представляет экспериментальную поддержку отложенной загрузки (deferred loading) для Wasm. Доступная под флагом на основном канале, эта функция позволяет разбивать Wasm-приложение на более мелкие, лениво загружаемые модули, что оптимизирует время начальной загрузки:
bash
Современная графика приходит на десктоп вместе с Impeller
Мы стремимся сделать десктопные платформы первоклассными целями для высокопроизводительной графики. Во Flutter 3.47 Impeller становится рендерером по умолчанию для macOS, Windows и Linux.
Если вы еще не знакомы с Impeller, это движок рендеринга Flutter нового поколения, созданный с нуля для замены Skia. Используя современные аппаратные API (такие как Metal в macOS и Vulkan в Windows и Linux), Impeller компилирует фиксированный набор шейдеров во время сборки, а не динамически во время выполнения. Это устраняет кратковременные задержки, называемые «jank» при компиляции шейдеров, которые возникают при первом воспроизведении анимации, обеспечивая стабильно плавные переходы с самого первого кадра. Узнайте больше в документации по движку рендеринга Impeller.
Если вам нужно временно отказаться от использования Impeller, выполните следующие действия:
- macOS: Установите FLTEnableImpeller в значение false в файле Info.plist.
- Windows: Добавьте project.set_impeller_switch(flutter::ImpellerSwitch::Disabled) в main.cpp.
- Linux: Вызовите fl_dart_project_set_enable_impeller(project, FALSE) в my_application.cc.
Опции отката будут удалены в будущих релизах, поэтому сообщайте об ошибках, если вам приходится возвращаться к использованию Skia. Кроме того, расширенная цветовая гамма (Wide Gamut Color) теперь активна по умолчанию в macOS, обеспечивая насыщенную, яркую и точную цветопередачу на поддерживаемом оборудовании.
Экспериментальная поддержка нескольких окон
В партнерстве с Canonical и благодаря мейнтейнерам @robert-ancell и @mattkae мы расширяем наши экспериментальные API для работы с окнами на десктопе. Linux и Windows теперь поддерживают всплывающие окна (#185866, #184516), что позволяет создавать нативные контекстные меню и палитры инструментов.
Теперь вы также можете запрашивать windowHandle у платформозависимых контроллеров, чтобы получить прямой указатель на базовое нативное окно (HWND, NSWindow или GtkWindow). Это открывает доступ к продвинутым нативным функциям, таким как стыкуемые панели (dockable panes) в Windows, как в этой демонстрации стыкуемых панелей, предоставленной @orestesgaolin:
Мы также исправили несколько ошибок, связанных с фокусом и реализацией окон. В Windows активация окна больше не выводит фоновые окна на передний план и не перехватывает фокус при возобновлении работы приложения, благодаря участнику @9AZX (#188016):
В Linux создание нескольких окон теперь явно реализует окна до того, как они получат свой первый кадр от композитора, что исправляет предупреждения о раннем рендеринге и утверждения композитора.
Мы также добавили новый API для изменения размера по содержимому (sized-to-content), который позволяет создавать обычные окна и диалоговые окна, автоматически подстраивающиеся под размер своего содержимого.
Флейворы (Flavors) для десктопа
Windows и Linux теперь поддерживают флейворы Flutter.
Например, ваш файл pubspec.yaml может использовать разные ресурсы для разных флейворов:
yaml
Используйте опцию --flavor, чтобы указать нужный флейвор. Например:
- flutter build windows --flavor flavor_a
- flutter build linux --flavor flavor_a
Спасибо @AngeloAvv за замечательный вклад (#187034, #187029)!
Более четкий текст на десктопе
Десктопные экраны часто имеют меньшую плотность пикселей, чем мобильные дисплеи, но обладают большей вычислительной мощностью графики. Чтобы обеспечить более четкий текст и более чистые векторные кривые на десктопе, движок Flutter с использованием Impeller теперь применяет рендеринг на основе знаковых функций расстояния (SDF) в macOS, Linux и Windows.
Стабильные превью и обновления GenUI
Предварительный просмотр виджетов стал стабильным
Flutter Widget Preview теперь стабилен, что позволяет мгновенно визуализировать, проверять и итерировать отдельные компоненты пользовательского интерфейса без сборки или запуска всего приложения.
С этим стабильным релизом вы можете ожидать:
- Более быстрое время запуска благодаря локальному кэшированию проекта в папке .widget_preview/, что устраняет накладные расходы на повторную настройку.
- Более гибкое тестирование с абстрактным API PreviewThemeData, который поддерживает последовательное наслоение тем для сложных матричных тестов.
- Автоматическая синхронизация веб-ресурсов при предварительном просмотре веб-виджетов, прямое копирование ресурсов web/ вашего хост-проекта, автоматическое применение пользовательских тем или настройка файла index.html при использовании Flutter web.
Дальнейшие достижения в GenUI
Экосистема Flutter продолжает развиваться, чтобы удовлетворить потребности разработчиков, использующих GenUI для создания новых типов агентных взаимодействий для своих пользователей. Недавно была выпущена версия 0.10.0 пакета genui, принесшая ряд исправлений и новых функций, среди которых:
- Новый пакет a2ui_core, который централизует классы, связанные с протоколом, включая такие вещи, как выражения, записи каталога и многое другое.
- Поддержка клиентских функций A2UI, которые позволяют предоставлять агенту функции, которые он может направлять клиенту для использования при проверке, вычислении производных значений и других небольших задачах без необходимости сетевого запроса.
Улучшение работы с платформой
В этом разделе освещаются целевые улучшения, внесенные сообществом и командой Flutter для полировки опыта разработчиков и пользователей на всех платформах.
Android
На Android мы решили проблему с виртуальной клавиатурой, из-за которой клавиши-модификаторы (например, Shift) могли «залипать» во время событий. Ответчик клавиш теперь пропускает синтез физических клавиш для ввода с виртуальной клавиатуры, сохраняя чистоту взаимодействия с клавиатурой.
Матрица зависимостей Android
Для обеспечения стабильных сборок Flutter 3.47 проверен на соответствие следующим версиям зависимостей Android:
- Java: 17 (минимально требуемая версия)
- Kotlin Gradle Plugin (KGP): 2.4.0
- Android Gradle Plugin (AGP): 9.1.0 (новейшая, совместимая с KGP 2.4.0)
- Gradle: 9.3.1 (минимально требуемая для AGP 9.1.0)
Чтобы гарантировать успешную сборку вашего приложения в будущих релизах, мы рекомендуем использовать стандартные переменные уровня API, предоставляемые Flutter SDK в ваших файлах сборки. Для этого релиза они настроены со следующими значениями по умолчанию:
- flutter.compileSdkVersion (API 36)
- flutter.targetSdkVersion (API 36)
- flutter.minSdkVersion (API 24)
iOS и macOS
Для разработчиков iOS подписание кода стало более прозрачным. Благодаря участнику сообщества @alex-medinsh, CLI теперь отображает как ID команды (Team ID), так и название команды (Team Name) при выборе сертификата (#184665).
Кроме того, участник сообщества @mozammal-hossain улучшил устранение неполадок, предоставив более понятные сообщения об ошибках профиля подготовки (provisioning profile) при сбое подписи (#184051).
Десктоп
Десктопные платформы также получили целевые улучшения. Позиционирование курсора при вводе корейского текста исправлено в Windows (спасибо @CHOIgoung, #186353), а плагины Windows теперь могут переносить ресурсоемкие задачи с платформенного потока с помощью FlutterEngine::PostPlatformThreadTask. В Linux @CodeDoctorDE добавил поддержку вращения стилуса и отчетности о давлении (#186831).
Графика и движок
В движке фрагментным шейдерам, нацеленным на OpenGLES, больше не требуется условное переворачивание координат при чтении текстур. Теперь это обрабатывается в вершинном шейдере. Обратитесь к странице критических изменений OpenGLES render-to-texture для получения более подробной информации.
Полировка фреймворка
Наконец, сам фреймворк стал более плавным, с улучшениями, распределенными по ключевым компонентам:
Специальные возможности и семантика: настройки высокой контрастности и инверсии цветов в Android теперь определяются автоматически благодаря @xxxOVALxxx (MediaQueryData.highContrast и MediaQueryData.invertColors, #182263). Вложенные текстовые диапазоны внутри Text.rich теперь соответствуют своей последовательности компоновки в дереве семантики, а для BlockSemantics добавлена блокировка фокуса клавиатуры.
Текст и выделение: маркеры выделения текста на мобильных устройствах теперь остаются стабильными во время незначительной прокрутки, а сочетания клавиш теперь могут закрывать открытые меню выделения. В Android маркеры выделения больше не перекрывают контекстное меню при расположении в верхней части экрана, спасибо @JhonaCodes (#182663).
Мы также исправили сбой в SelectableRegion, возникавший при начале выделения в пустом прокручиваемом контейнере, и устранили визуальные артефакты подсветки на выцветшем выделяемом тексте, спасибо @ikramhasan (#183628).
Жесты и прокрутка: улучшено распространение жестов для нативных представлений iOS, встроенных через платформенные представления. EdgeDraggingAutoScroller теперь учитывает ScrollPhysics активного представления прокрутки, предотвращая автопрокрутку в заблокированных списках.
Улучшения основных виджетов: сохранение исходных цветов внутри ImageIcon с помощью useOriginalColors: true (#180491), указание поведения обрезки в AnimatedCrossFade (#184545) и отслеживание ошибок потока изображений напрямую с помощью ImageStreamListener.
Готовы к обновлению
Все готово, фундамент заложен. Осталось только перенести эти обновления на вашу локальную машину:
bash
Пока ваш SDK обновляется в фоновом режиме, у нас есть для вас домашнее задание (из приятных):
- Познакомьтесь с участниками: запасайтесь попкорном и включайте нашу новую серию видео «Представляем: значимые коммиты Flutter», в которой мы чествуем участников сообщества, сделавших этот релиз возможным.
- Проверьте детали: бегло просмотрите страницу критических изменений (Breaking Changes), чтобы подготовиться к миграции автономных пакетов пользовательского интерфейса.
Мы с нетерпением ждем, что вы создадите с помощью этой новой и улучшенной версии Flutter!









