Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Всем привет! Я — Евгений Сатуров, Flutter TeamLead в Surf. Представляю перевод официальной статьи про свежий апдейт Flutter 1.22 — как обычно, дополненный моими комментариями.
Этот релиз — один из самых примечательных для меня за всё последнее время. Мы движемся вперёд не только за счёт появления новых виджетов, которыми уже никого не удивишь, но и благодаря серьёзным инфраструктурным изменениям, а также оперативной поддержке новых операционных систем. То ли ещё будет!
Погнали ближе знакомиться с новой версией Flutter 1.22.
Мы рады представить последний релиз Flutter с обширной поддержкой iOS 14 и Android 11. Flutter 1.22 основан на фундаменте, заложенном предыдущими версиями, и позволяет разработчикам создавать быстрые и красивые пользовательские интерфейсы для нескольких платформ из единой кодовой базы. В наших ежеквартальных stable релизах — новые функции, улучшенная производительность и bug fix’ы.
Недавно вышли новые версии мобильных ОС. Мы сфокусировались на том, чтобы Android 11 и iOS 14 превосходно работали на этом релизе Flutter.
Обновление Flutter для iOS 14: поддержка нового Xcode 12, новых иконок и поддержка App Clips — аналога Instant Apps для Android.
Обновление Flutter для Android 11: добавили поддержку разных типов «чёлок» у дисплеев, а также более плавную анимацию при вызове soft keyboard.
Этот релиз выходит всего через два месяца после выхода версии 1.20, но даже за это небольшое время мы закрыли 3024 issues и замёрджили 1944 PR от 197 контрибьюторов.
Вдобавок к поддержке новых версий мобильных ОС, у нас есть и другие новости, включая предварительную версию одной из наиболее востребованных функций для Android:
Ещё у нас есть новый инструмент для анализа размера приложений. Кроме того, теперь разработчики могут создавать плагины только для тех платформ, которые им нужны, явно указывая целевые платформы в конфигурации плагина.
Каждый раз, когда анонсируется новая версия мобильной ОС, мы тщательно её тестируем: ищем несовместимости или изменения, которые могут повлиять на работу Flutter и его инструментов.
В случае с iOS 14 мы сделали некоторые изменения во Flutter, чтобы убедиться, что он будет работать ровно так, как того хотят разработчики:
Итог: если iOS 14 — целевая платформа для вашего Flutter-приложения, мы настоятельно рекомендуем вам пересобрать его с помощью Flutter 1.22 и задеплоить его в App Store прямо сейчас, чтобы обеспечить наилучший пользовательский опыт для тех, у кого iOS 14.
Дополнительную информацию, включая некоторые соображения по поводу Add-to-App, дип линкам и уведомлениям, смотрите в документации iOS 14 на flutter.dev.
Отдельно хотим сказать про обновлённую поддержку нового шрифта iOS SF Symbols, который вдохновил нас потратить некоторое время на обновление пакета cupertino_icon. Существующие варианты использования
Полный список иконок вы найдёте на странице предварительного просмотра cupertino_icons и на странице сведений о миграции на flutter.dev.
Еще одна функция, которую вы можете попробовать с Flutter на iOS 14, — это App Clips. App Clips — новая фича iOS 14: это мини-приложения весом до 10 мб. Они дают пользователю доступ к определённым функциям без необходимости загружать полное приложение из AppStore. Flutter версии 1.22 умеет работать с App Clips в предварительном варианте реализации.
App Clips на Flutter
Подробнее о том, как создавать App Clips приложений с помощью Flutter, — в документации на flutter.dev. Посмотрите также образец простого проекта.
Этот релиз Flutter вышел практически одновременно с релизом Android 11. Фреймворк и движок Flutter обновились, чтобы поддерживать две новые фичи, представленные в последней версии Android.
Во-первых, Flutter теперь учитывает расположение «чёлок» и вырезов на экране Android-телефона, а также закруглённые края экрана.
Используя API MediaQuery и SafeArea, теперь легко написать UI, в котором интерактивные области не будут попадать на вырезы и закруглённые края экрана.
Видимая область приложения меняет размер не скачком, а плавно. Контент приложения скроллится синхронно с появлением экранной клавиатуры.
Обратите внимание на FAB
Issue №19279 — давняя проблема, когда анимация отображения / скрытия экранной клавиатуры не синхронизируется с Flutter inset. Для Android 11 это исправлено.
Раньше из-за плагинов Flutter были проблемы, когда в нативное Android-приложение вставляли Flutter-код. Мы переписали API для интеграции Flutter c Android и выпустили API v2, которая лишена этих недостатков. Начиная с версии 1.22, мы прекращаем поддержку старых API v1.
Если вы продолжаете использовать Android v1 API, вот что это для вас значит:
Между тем, если у вас всё ещё есть приложение Flutter на основе API версии 1 для Android, оно продолжит работать. Однако вы можете начать встречать новые плагины, у которых целевая — API v2. Они не могут использоваться API v1 для Android. Дополнительные сведения см. В документации по критическим изменениям.
Существующие Flutter кнопки красиво выглядят, но их может быть трудно использовать, особенно если вам нужны кастомные темы. Кроме того, Material спецификация была расширена за счёт включения новых кнопок с новыми стилями.
Чтобы идти в ногу с Material гайдлайнами, мы представляем новую «вселенную» кнопок во Flutter 1.22.
Новая «вселенная» Material design кнопок
У новых виджетов и тем новые имена классов. Мы переименовали классы во Flutter, чтобы они соответствовали спецификации Material Design.
Новые темы следуют «нормализованному» шаблону, который Flutter недавно принял для новых виджетов Material. Демо-версия на DartPad
Это не критическое изменение, поскольку семантика
Основные функции, необходимые для интернационализации (i18n) и локализации (l10n) ваших приложений, доступны во Flutter с самого начала. В этом релизе мы сделали поддержку Hot reload для обновления вашего приложения по мере добавления новой l10n информации.
Если вам нужна дополнительная информация о поддержке Flutter’ом l10n, включая локализованные сообщения, сообщения с параметрами, датами, числами и валютами, прочтите Flutter Internationalization User Guide.
Кроме того, если вас интересуют i18n и l10n, вам, возможно, потребуется использовать строки с символами, которые не вписываются в простой старый ASCII — например, Unicode и эмодзи. Недавно команда Dart выпустила characters package, который помогает разработчикам работать с кластерами графем Unicode (расширенным). Этот пакет помогает решить проблемы, например, как правильно сократить строку типа «A [эмодзи британского флага] text in English» до первых 15 символов. Используя класс
С этим PR Flutter использует пакет символов для правильной обработки этих сложных символов. Например, при использовании
В команде Flutter мы часто опасаемся маркировать что-либо как «готовое к использованию в продакшене», пока не проверим это самостоятельно. В случае плагинов google_maps_flutter и webview_flutter основная причина задержки была в базовой реализации Platform Views, которая позволяет размещать собственные компоненты пользовательского интерфейса как Android, так и iOS в приложении Flutter. В этом выпуске Flutter мы рады сообщить, что мы достаточно укрепили инфраструктуру, чтобы объявить оба этих плагина готовыми к использованию.
webview_flutter plugin, отображающий flutter.dev
Во Flutter 1.22 мы добавили альтернативную реализацию Platform Views, которая устраняет все известные проблемы с клавиатурой и проблемы доступности на Android Views. Это работает с Android API уровня 19 и выше (раньше требовался уровень 20). Мы также внесли улучшения в потоки в iOS, которые делают platform views более эффективными и надёжными (и больше не требует добавления флага
Плагин
Плагины Google Maps и WebView уже выиграли от улучшений в Platform Views.
Если хотите использовать Platform Views, чтобы размещать собственные UI-элементы в iOS и Android, прочитайте подробнее про нативные Android и iOS views в приложении Flutter.
Если вы раньше использовали навигацию в своих приложениях Flutter, возможно, вы заметили, что основная структура данных, стек страниц, по которым перемещается пользователь, скрыта от вас. Вместо этого, чтобы управлять ею, вы вызываете
Предположим, что вы хотите отобразить список виджетов на своей домашней странице и позволить пользователю нажать на один из них, чтобы перейти на страницу сведений, посвящённую именно этому цвету.
Два экрана можно реализовать так:
Использование простейшего стиля Navigator 1.0 позволяет вам перемещаться между этими двумя экранами. Это выглядит довольно легко:
Вызов
Navigator 2.0 решает эти и другие проблемы, делая стек страниц видимым. Вот обновленный пример перехода между одним и тем же
Приложение явно создаёт
Вы обновляете своё состояние в обратном вызове
Если Navigator 2.0 выглядит как остальная часть Flutter, это нарочно: он декларативен, в отличие от императивного Navigator 1.0. Идея заключалась в том, чтобы объединить модели навигации и остальной части Flutter, одновременно исправляя множество багов и добавляя фичи. Фактически, этот небольшой пример лишь поверхностно описывает то, что есть в Navigator 2.0. Для подробностей я настоятельно рекомендую статью о декларативной навигации и маршрутизации во Flutter.
Вы можете продолжать использовать Navigator 1.0: он будет работать так же, как и раньше. В ближайшее время мы не будем его удалять. Однако мы думаем, что если вы попробуете Navigator 2.0, он вам понравится.
Новая функция, с которой вы можете поэкспериментировать в этом выпуске, — это поддержка восстановления состояния на Android. Это одна из наших самых желанных функций, получившая 217 отзывов!
Для тех, кто не знаком с необходимостью восстановления состояния: мобильные ОС могут «убивать» приложения, которые находятся в фоновом режиме, чтобы освободить ресурсы для приоритетных приложений. Когда это происходит, ОС уведомляет приложение, которое она собирается «убить»: приложение быстро сохраняет состояние пользовательского интерфейса, чтобы восстановить его, когда пользователь вернётся к приложению.
При правильной реализации пользователь получает бесшовный опыт, при этом ресурсы устройства расходуются более эффективно. До сих пор Flutter не поддерживал восстановление состояния, и без поддержки фреймворка было очень сложно сделать это правильно. Поэтому мы очень рады предоставить основную реализацию этой функции для Android.
Вот очень простой пример восстановления состояния дефолтного приложения Flutter Counter:
Вкратце, каждый виджет получает сегмент хранилища, который регистрируется в RestorationMixin с использованием уникального идентификатора. Используя тип RestorableProperty (например,
Для автоматического тестирования восстановления состояния мы добавили в WidgetTester новый API restartAndRestore. А для тестирования вручную проще всего:
Android «убьет» и восстановит ваше приложение, и вы увидите, всё ли работает так, как вы ожидаете.
Эта версия восстановления состояния предварительная: предстоит ещё кое-что доделать. Например, восстановление состояния — фича не только для Android, приложения для iOS тоже смогут от этого выиграть. Кроме того, мы заняты обновлением собственных виджетов, чтобы сохранять их состояние во время восстановления. Мы сделали поддержку классов
Правда, мы еще не добавили ключевую функцию — поддержку навигации (1.0 или 2.0), поэтому и называем эту версию «предварительной». То есть приложение не откроется на том же месте, где пользователь находился. Эта функция скоро появится в бета-версии и в следующей стабильной версии Flutter.
Работая с нашими внутренними партнёрами из Google, команда Flutter значительно улучшила производительность прокрутки, когда частота ввода и отображения не совпадают. Например, вход Pixel 4 работает с частотой 120 Гц, а дисплей работает с частотой 90 Гц. Это несоответствие может привести к снижению производительности при прокрутке. С новым флагом
В зависимости от рассматриваемых частотных несоответствий, вы можете увидеть до 97% меньше задержек при прокрутке, если включите этот флаг. В будущих сборках мы планируем включить этот флаг по умолчанию.
Как всегда, обновление Flutter касается не только движка и фреймворка, но и инструментов. Flutter 1.22 включает новую версию Dart (2.10), а также новый инструмент командной строки
Исторически у Dart было много небольших инструментов для разработчиков (таких как
Начиная с Flutter 1.22 SDK, в папке
Инструменты, выпущенные как часть Flutter 1.22, включают новую утилиту анализа размера сборки. Этот инструмент помогает диагностировать, не раздувается ли размер вашего приложения с течением времени.
Вы можете использовать этот инструмент, чтобы собирать данные для анализа. Передайте флаг
Использование этого флага при построении выходного артефакта Flutter выводит сводку о размере и составе артефакта. Она включает нативный код, ресурсы и даже разбивку на уровне пакета скомпилированного кода Dart.
Пример разбивки релизного APK Flutter Gallery
Эта сводка полезна, чтобы быстро проанализировать размер сборки и понять, из-за чего она слишком большая. Кроме того, собранные данные также доступны в виде файла JSON, который можно посмотреть в Dart DevTools, что позволяет дополнительно исследовать содержимое приложения, выявлять проблемы с размером и видеть изменения между двумя разными файлами JSON, следуя инструкциям на flutter.dev. После загрузки файла JSON у вас будет интерфейс, в котором отображается древовидная карта размера вашего приложения.
Пример разбивки APK в Dart DevTools
Документации по инструменту анализа размера приложения на сайте flutter.dev
Еще одна предварительная функция DevTools в этом выпуске: теперь во вкладке Network отображается body запроса.
Чтобы включить эту функцию, убедитесь, что вы находитесь на dev-канале Flutter через
Кроме того, для приложений с большим объёмом сетевого трафика мы предусмотрели возможность поиска и фильтрации.
Документацию по вкладке Network ищите в разделе Использование Network View на flutter.dev.
Уже некоторое время мы поддерживаем две копии некоторых наших инструментов Flutter: например, панель Inspector в IntelliJ и вкладку Inspector в Dart DevTools. Это замедляет нашу работу: нам нужно поддерживать две кодовые базы. Кроме того, некоторые функции еще не вошли в плагин IntelliJ — например, Layout Explorer. Чтобы решить эти проблемы, мы включили возможность размещения вкладки Inspector из Dart DevTools непосредственно внутри IntelliJ.
Чтобы включить эту опцию, перейдите в Preferences > Languages & Frameworks > Flutter > Enable embedded DevTools inspector.
Обычное действие, с которым сталкиваются все разработчики Flutter, — переход из стектрейсов ошибок в терминале к месту в исходном коде, где произошла ошибка. В самом последнем выпуске расширения Flutter для Visual Studio Code эти ссылки теперь парсятся правильно: по ним можно кликнуть и перейти в нужное место кода, в котором произошло падение.
Это кажется мелочью, но первоначальные отзывы об этой функции уже очень положительные.
Как всегда, здесь слишком много списка изменений инструментов, но я рекомендую изучить следующие анонсы:
EasyA — это приложение по подписке: школьники занимаются с блестящим репетиторам через обмен мгновенными сообщениями. Приложение написано на Flutter. Недавно Apple отметила его как приложение дня.
Как всегда, мы стараемся свести количество критических изменений к минимуму. Вот список из версии Flutter 1.22:
Этот релиз — один из самых примечательных для меня за всё последнее время. Мы движемся вперёд не только за счёт появления новых виджетов, которыми уже никого не удивишь, но и благодаря серьёзным инфраструктурным изменениям, а также оперативной поддержке новых операционных систем. То ли ещё будет!
Погнали ближе знакомиться с новой версией Flutter 1.22.
Мы рады представить последний релиз Flutter с обширной поддержкой iOS 14 и Android 11. Flutter 1.22 основан на фундаменте, заложенном предыдущими версиями, и позволяет разработчикам создавать быстрые и красивые пользовательские интерфейсы для нескольких платформ из единой кодовой базы. В наших ежеквартальных stable релизах — новые функции, улучшенная производительность и bug fix’ы.
Недавно вышли новые версии мобильных ОС. Мы сфокусировались на том, чтобы Android 11 и iOS 14 превосходно работали на этом релизе Flutter.
Обновление Flutter для iOS 14: поддержка нового Xcode 12, новых иконок и поддержка App Clips — аналога Instant Apps для Android.
Обновление Flutter для Android 11: добавили поддержку разных типов «чёлок» у дисплеев, а также более плавную анимацию при вызове soft keyboard.
Этот релиз выходит всего через два месяца после выхода версии 1.20, но даже за это небольшое время мы закрыли 3024 issues и замёрджили 1944 PR от 197 контрибьюторов.
Комментарий
Кстати, если вы давно хотите стать контрибьютором Flutter, но не знаете с чего начать, вот вам пара советов. Фильтруйте issues по тэгу good first contribution: время от времени там появляются интересные задачи, с которых можно начать свой путь в опенсорс. Также вы можете реализовать фичу чьей-то мечты, отфильтровав issues по тэгу new feature. Там есть задачки даже для начинающих. Вы сможете увековечить своё имя в истории фреймворка — конечно, в том случае, если разработчики Flutter-team согласны с тем, что такая фича должна быть реализована.
Вдобавок к поддержке новых версий мобильных ОС, у нас есть и другие новости, включая предварительную версию одной из наиболее востребованных функций для Android:
- восстановление состояния,
- новая «вселенная» Material кнопок,
- новая библиотека для поддержки локализации и интернационализации, работающая с Hot Reload,
- новый Navigator,
- стабильная версия для Platform Views (основа для плагинов Google Maps и WebView),
- переключатель, который вы можете добавить свой код, чтобы улучшить прокрутку на устройствах с высокочастотными дисплеями.
Ещё у нас есть новый инструмент для анализа размера приложений. Кроме того, теперь разработчики могут создавать плагины только для тех платформ, которые им нужны, явно указывая целевые платформы в конфигурации плагина.
Целевая платформа iOS 14
Каждый раз, когда анонсируется новая версия мобильной ОС, мы тщательно её тестируем: ищем несовместимости или изменения, которые могут повлиять на работу Flutter и его инструментов.
В случае с iOS 14 мы сделали некоторые изменения во Flutter, чтобы убедиться, что он будет работать ровно так, как того хотят разработчики:
- Xcode 12 требует iOS 9.0 или выше, поэтому в нашем шаблон по умолчанию теперь вместо версии платформы 8.0 указана версия 9.0.
- В Flutter 1.22 были исправлены специфические сбои iOS 14 и проблемы с отрисовкой шрифтов.
- Проблемы с развёртыванием на физические устройства (приложение не запускалось на устройстве — только на эмуляторе) были исправлены в Flutter 1.20.4.
- Новая политика, которая показывает уведомления, когда приложения обращаются к своему буферу обмена, вызвала ложные уведомления в приложениях Flutter и была исправлена в Flutter 1.20.4.
- Новая политика сетевой безопасности для локальной отладки приложений Flutter заставляет iOS 14 показывать одноразовое диалоговое окно подтверждения (только во время разработки, а не для выпущенных Flutter-приложений).
Итог: если iOS 14 — целевая платформа для вашего Flutter-приложения, мы настоятельно рекомендуем вам пересобрать его с помощью Flutter 1.22 и задеплоить его в App Store прямо сейчас, чтобы обеспечить наилучший пользовательский опыт для тех, у кого iOS 14.
Дополнительную информацию, включая некоторые соображения по поводу Add-to-App, дип линкам и уведомлениям, смотрите в документации iOS 14 на flutter.dev.
Отдельно хотим сказать про обновлённую поддержку нового шрифта iOS SF Symbols, который вдохновил нас потратить некоторое время на обновление пакета cupertino_icon. Существующие варианты использования
CupertinoIcons
будут автоматически отображаться в новом стиле, как только вы обновите зависимость cupertino_icons
до новой основной версии 1.0. Если вы используете cupertino_icons
1.0 вместе с Flutter 1.22, у вас будет доступ к ~ 900 новым иконкам через API CupertinoIcons.Полный список иконок вы найдёте на странице предварительного просмотра cupertino_icons и на странице сведений о миграции на flutter.dev.
Еще одна функция, которую вы можете попробовать с Flutter на iOS 14, — это App Clips. App Clips — новая фича iOS 14: это мини-приложения весом до 10 мб. Они дают пользователю доступ к определённым функциям без необходимости загружать полное приложение из AppStore. Flutter версии 1.22 умеет работать с App Clips в предварительном варианте реализации.
App Clips на Flutter
Подробнее о том, как создавать App Clips приложений с помощью Flutter, — в документации на flutter.dev. Посмотрите также образец простого проекта.
Комментарий
Помните Instant Apps for Android? Похоже, Apple решили вернуть наш 2017 год и представили аналогичное решение — App Clips. Более того, вы можете реализовать App Clips даже в том случае, если пишете не нативное приложение, а кроссплатформенное.
Не забывайте про ограничения: если ваша сборка весит более 10 Мб, то запустить её в формате App Clips не получится. В случае с Flutter-приложением это может быть действительно актуальной проблемой. Но об этом вы узнаете во второй половине статьи: там мы расскажем, как вы сможете мониторить размер сборки вашего приложения при помощи удобного инструмента.
Android 11
Этот релиз Flutter вышел практически одновременно с релизом Android 11. Фреймворк и движок Flutter обновились, чтобы поддерживать две новые фичи, представленные в последней версии Android.
Во-первых, Flutter теперь учитывает расположение «чёлок» и вырезов на экране Android-телефона, а также закруглённые края экрана.
Используя API MediaQuery и SafeArea, теперь легко написать UI, в котором интерактивные области не будут попадать на вырезы и закруглённые края экрана.
Видимая область приложения меняет размер не скачком, а плавно. Контент приложения скроллится синхронно с появлением экранной клавиатуры.
Обратите внимание на FAB
Issue №19279 — давняя проблема, когда анимация отображения / скрытия экранной клавиатуры не синхронизируется с Flutter inset. Для Android 11 это исправлено.
Раньше из-за плагинов Flutter были проблемы, когда в нативное Android-приложение вставляли Flutter-код. Мы переписали API для интеграции Flutter c Android и выпустили API v2, которая лишена этих недостатков. Начиная с версии 1.22, мы прекращаем поддержку старых API v1.
Если вы продолжаете использовать Android v1 API, вот что это для вас значит:
- Новые плагины создаются без поддержки v1 API.
- Флаг конфигурации инструмента Flutter
—no-enable-android-embedding-v2
был удалён. Теперь это поведение по умолчанию.
- В более старых приложениях, всё ещё использующих API v1, во время сборки будет отображаться предупреждение об устаревании, которое ссылается на документацию по поддержке новых API-интерфейсов плагинов Android.
Между тем, если у вас всё ещё есть приложение Flutter на основе API версии 1 для Android, оно продолжит работать. Однако вы можете начать встречать новые плагины, у которых целевая — API v2. Они не могут использоваться API v1 для Android. Дополнительные сведения см. В документации по критическим изменениям.
Комментарий
Пожалуй, основным страхом разработчиков относительно Flutter была неуверенность в оперативной поддержке новых фич операционных систем, которые могут быть использованы в нативных решениях уже с первого дня. На примере релиза 1.22 мы видим, что поддержка всех новых возможностей платформ — приоритет для команды. Даже App Clips, который (я уверен) не найдёт широкого применения, уже доступен к реализации. А что касается Android, куда более важное изменение в новом релизе, касающееся его, — это сохранение состояния экрана после смерти процесса. О нём ниже.
Расширение «вселенной» кнопок
Существующие Flutter кнопки красиво выглядят, но их может быть трудно использовать, особенно если вам нужны кастомные темы. Кроме того, Material спецификация была расширена за счёт включения новых кнопок с новыми стилями.
Чтобы идти в ногу с Material гайдлайнами, мы представляем новую «вселенную» кнопок во Flutter 1.22.
Новая «вселенная» Material design кнопок
У новых виджетов и тем новые имена классов. Мы переименовали классы во Flutter, чтобы они соответствовали спецификации Material Design.
Новые темы следуют «нормализованному» шаблону, который Flutter недавно принял для новых виджетов Material. Демо-версия на DartPad
Это не критическое изменение, поскольку семантика
FlatButton
, OutlineButton
, RaisedButton
, ButtonBar
, ButtonBarTheme
и ButtonTheme
не изменится. Вы можете смешивать и сочетать старые кнопки с новыми. Новая поддержка интернационализации и локализации
Основные функции, необходимые для интернационализации (i18n) и локализации (l10n) ваших приложений, доступны во Flutter с самого начала. В этом релизе мы сделали поддержку Hot reload для обновления вашего приложения по мере добавления новой l10n информации.
Если вам нужна дополнительная информация о поддержке Flutter’ом l10n, включая локализованные сообщения, сообщения с параметрами, датами, числами и валютами, прочтите Flutter Internationalization User Guide.
Кроме того, если вас интересуют i18n и l10n, вам, возможно, потребуется использовать строки с символами, которые не вписываются в простой старый ASCII — например, Unicode и эмодзи. Недавно команда Dart выпустила characters package, который помогает разработчикам работать с кластерами графем Unicode (расширенным). Этот пакет помогает решить проблемы, например, как правильно сократить строку типа «A [эмодзи британского флага] text in English» до первых 15 символов. Используя класс
String
, это сокращение будет «A [эмодзи британского флага] text in», что составляет всего 12 символов, воспринимаемых пользователем. С другой стороны, использование пакета characters
даёт правильное сокращение «A [эмодзи британского флага] text in Eng».С этим PR Flutter использует пакет символов для правильной обработки этих сложных символов. Например, при использовании
TextField
с ограничением maxLength
такие символы, как [эмодзи семьи из трёх человек], теперь правильно считаются как один символ. Кроме того, с этим PR пакет символов доступен в Flutter-проектах автоматически, без необходимости добавлять его вручную. Надеюсь, это упростит работу со строками всех типов из всех локалов. Чтобы узнать больше о пакете символов, ознакомьтесь с отличной статьёй «Правильные манипуляции со строками в Dart».Плагины Google Maps и WebView можно использовать в продакшн-приложении
В команде Flutter мы часто опасаемся маркировать что-либо как «готовое к использованию в продакшене», пока не проверим это самостоятельно. В случае плагинов google_maps_flutter и webview_flutter основная причина задержки была в базовой реализации Platform Views, которая позволяет размещать собственные компоненты пользовательского интерфейса как Android, так и iOS в приложении Flutter. В этом выпуске Flutter мы рады сообщить, что мы достаточно укрепили инфраструктуру, чтобы объявить оба этих плагина готовыми к использованию.
webview_flutter plugin, отображающий flutter.dev
Во Flutter 1.22 мы добавили альтернативную реализацию Platform Views, которая устраняет все известные проблемы с клавиатурой и проблемы доступности на Android Views. Это работает с Android API уровня 19 и выше (раньше требовался уровень 20). Мы также внесли улучшения в потоки в iOS, которые делают platform views более эффективными и надёжными (и больше не требует добавления флага
io.flutter.embedded_views_preview
в ваш iOS Info.plist
).Плагин
webview_flutter
поддерживает новый режим Android Platform Views, но в настоящее время его необходимо включить вручную. Когда он получит большее распространение в сообществе, мы включим его по умолчанию.Плагины Google Maps и WebView уже выиграли от улучшений в Platform Views.
Если хотите использовать Platform Views, чтобы размещать собственные UI-элементы в iOS и Android, прочитайте подробнее про нативные Android и iOS views в приложении Flutter.
Комментарий
Ещё одно приятное событие, которое не привносит никаких революционных изменений в жизнь разработчика. Мы уже давно используем оба этих плагина в проде и не испытываем никаких затруднений. Надеемся, выход в «продакшн реди» стадию не изменит эту ситуацию. Гораздо больше мы были бы рады появлению официального плагина для поддержки Yandex MapKit. Пока такого нет, остаётся лишь пользоваться сторонними решениями.
Навигатор 2.0
Если вы раньше использовали навигацию в своих приложениях Flutter, возможно, вы заметили, что основная структура данных, стек страниц, по которым перемещается пользователь, скрыта от вас. Вместо этого, чтобы управлять ею, вы вызываете
Navigator.pop()
или Navigator.push()
. Предположим, что вы хотите отобразить список виджетов на своей домашней странице и позволить пользователю нажать на один из них, чтобы перейти на страницу сведений, посвящённую именно этому цвету.
Два экрана можно реализовать так:
class ColorListScreen extends StatelessWidget {
final List<Color> colors;
final void Function(Color color) onTapped;
ColorListScreen({this.colors, this.onTapped});
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: Text('Colors')),
body: Column(
children: [
// you can see and decide on every color in this list
for (final color in colors)
Expanded(
child: GestureDetector(
child: Container(color: color),
onTap: () => onTapped(color),
),
)
],
),
);
}
class ColorScreen extends StatelessWidget {
final Color color;
const ColorScreen({this.color});
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: Text('Color')),
body: Container(color: color),
);
}
Использование простейшего стиля Navigator 1.0 позволяет вам перемещаться между этими двумя экранами. Это выглядит довольно легко:
class _ColorAppState extends State<ColorApp> {
List<Color> _colors = [Colors.red, Colors.green, Colors.blue];
@override
Widget build(BuildContext context) => MaterialApp(
title: 'Color App',
home: Builder(
builder: (context) => ColorListScreen(
colors: _colors,
// the Navigator manages the list of pages itself; you can only push and pop
onTapped: (color) => Navigator.push(
context,
MaterialPageRoute(builder: (context) => ColorScreen(color: color)),
),
),
),
);
}
Вызов
Navigator.push()
— это всё что нужно, чтобы поместить другую страницу поверх первой, создав стек из двух страниц. Однако, в отличие от списка контейнеров, созданного в методе сборки ColorListScreen
, этот стек скрыт от вас. А поскольку он скрыт, им трудно управлять в других сценариях, таких как обработка диплинков initial route, предоставленным, например, нативным встраиванием, или URL-адресом из интернета или намерением из Android. Также чрезвычайно сложно управлять вложенной маршрутизацией между различными структурами одной и той же страницы.Navigator 2.0 решает эти и другие проблемы, делая стек страниц видимым. Вот обновленный пример перехода между одним и тем же
ColorListScreen
и ColorScreen
:class _ColorAppState extends State<ColorApp> {
Color _selectedColor;
List<Color> _colors = [Colors.red, Colors.green, Colors.blue];
@override
Widget build(BuildContext context) => MaterialApp(
title: 'Color App',
home: Navigator(
// you can see and decide on every page in this list
pages: [
MaterialPage(
child: ColorListScreen(
colors: _colors,
onTapped: (color) => setState(() => _selectedColor = color),
),
),
if (_selectedColor != null) MaterialPage(child: ColorScreen(color: _selectedColor)),
],
onPopPage: (route, result) {
if (!route.didPop(result)) return false;
setState(() => _selectedColor = null);
return true;
},
),
);
}
Приложение явно создаёт
Navigator
и предоставляет ему список страниц, представляющий полный стек. Мы создаём пустой _selectedColor
, чтобы указать, что цвет еще не выбран, поэтому изначально мы не показываем ColorScreen
. Когда пользователь выбирает цвет, мы вызываем setState()
как обычно, чтобы указать Flutter, что вы хотите снова вызвать метод build()
, который теперь создаёт стек с ColorScreen
наверху.Вы обновляете своё состояние в обратном вызове
OnPopPage
: например, если пользователь вернулся на экран назад, значит, он «отменил выбор» текущего цвета, и мы больше не хотим отображать эту страницу.Если Navigator 2.0 выглядит как остальная часть Flutter, это нарочно: он декларативен, в отличие от императивного Navigator 1.0. Идея заключалась в том, чтобы объединить модели навигации и остальной части Flutter, одновременно исправляя множество багов и добавляя фичи. Фактически, этот небольшой пример лишь поверхностно описывает то, что есть в Navigator 2.0. Для подробностей я настоятельно рекомендую статью о декларативной навигации и маршрутизации во Flutter.
Вы можете продолжать использовать Navigator 1.0: он будет работать так же, как и раньше. В ближайшее время мы не будем его удалять. Однако мы думаем, что если вы попробуете Navigator 2.0, он вам понравится.
Комментарий
Противоречивые чувства. С одной стороны, новый навигатор стал декларативным. Для некоторых кейсов это однозначный плюс, хотя, скорее всего, вам придётся поломать голову, чтобы научиться проектировать декларативную навигацию. Слишком уж этот подход отличается от императивного.
С другой стороны, сообщество ждало от нового навигатора гораздо большего. Реализовать вложенную навигацию — всё ещё крайне нетривиальная задача для Flutter. И Navigator 2.0 не привнёс никаких улучшений на этом поприще. Известный разработчик Remi Rousselet даже заявил в Twitter, что напишет свой навигатор. Будет любопытно посмотреть, что у него получится. А пока рекомендую опробовать наше собственное решение для реализации вложенной навигации — мы разработали его в Surf. Заодно, кстати, рекомендую посетить наш публичный репозиторий на GitHub: мы выкладываем там библиотеки, стандарты, инструменты, которыми пользуемся сами.
Предварительная версия: Восстановление состояния для Android
Новая функция, с которой вы можете поэкспериментировать в этом выпуске, — это поддержка восстановления состояния на Android. Это одна из наших самых желанных функций, получившая 217 отзывов!
Для тех, кто не знаком с необходимостью восстановления состояния: мобильные ОС могут «убивать» приложения, которые находятся в фоновом режиме, чтобы освободить ресурсы для приоритетных приложений. Когда это происходит, ОС уведомляет приложение, которое она собирается «убить»: приложение быстро сохраняет состояние пользовательского интерфейса, чтобы восстановить его, когда пользователь вернётся к приложению.
При правильной реализации пользователь получает бесшовный опыт, при этом ресурсы устройства расходуются более эффективно. До сих пор Flutter не поддерживал восстановление состояния, и без поддержки фреймворка было очень сложно сделать это правильно. Поэтому мы очень рады предоставить основную реализацию этой функции для Android.
Вот очень простой пример восстановления состояния дефолтного приложения Flutter Counter:
class CounterState extends State<RestorableCounter> with RestorationMixin {
@override
String get restorationId => widget.restorationId;
RestorableInt _counter = RestorableInt(0);
@override
void restoreState(RestorationBucket oldBucket) => registerForRestoration(_counter, 'count');
void _incrementCounter() => setState(() => _counter.value++);
@override
Widget build(BuildContext context) => Scaffold(
body: Center(child: Text('${_counter.value}')),
floatingActionButton: FloatingActionButton(onPressed: _incrementCounter),
);
}
Вкратце, каждый виджет получает сегмент хранилища, который регистрируется в RestorationMixin с использованием уникального идентификатора. Используя тип RestorableProperty (например,
RestorableInt
, как здесь) для хранения UI-специфичных данных и регистрируя эти данные с помощью функции восстановления состояния, данные автоматически сохраняются до того, как Android завершает работу приложения, и восстанавливаются, когда оно возвращается к жизни. И это всё. Все данные, которые хранятся в типе Restoration*
, например RestorableInt
, RestorableString
и RestorableTextEditingController
(у нас их несколько), будут восстановлены. И если мы не охватыватили все типы, которые вы хотели бы восстановить, вы можете создать свой собственный, расширив RestorableProperty.Для автоматического тестирования восстановления состояния мы добавили в WidgetTester новый API restartAndRestore. А для тестирования вручную проще всего:
- запустить приложение Flutter с включенным восстановлением состояния на устройстве Android,
- включить параметр «Не сохранять действия» в настройках разработчика Android,
- запустить приложение Flutter,
- поместить его в фоновый режим,
- вернуться к нему.
Android «убьет» и восстановит ваше приложение, и вы увидите, всё ли работает так, как вы ожидаете.
Эта версия восстановления состояния предварительная: предстоит ещё кое-что доделать. Например, восстановление состояния — фича не только для Android, приложения для iOS тоже смогут от этого выиграть. Кроме того, мы заняты обновлением собственных виджетов, чтобы сохранять их состояние во время восстановления. Мы сделали поддержку классов
Scrollable
, таких как ListView
и SingleChildScrollView
(для запоминания позиции прокрутки пользователя) и TextFields
(для восстановления введённого текста), и планируем распространить её на другие виджеты.Правда, мы еще не добавили ключевую функцию — поддержку навигации (1.0 или 2.0), поэтому и называем эту версию «предварительной». То есть приложение не откроется на том же месте, где пользователь находился. Эта функция скоро появится в бета-версии и в следующей стабильной версии Flutter.
Комментарий
С одной стороны — прорыв. Flutter-приложение всё меньше отличается от нативного в плане UX. С другой — реализация довольно тяжеловесная, особенно если вы хотите сохранять не только состояние отдельных виджетов (например, текстовых полей — они будут сохраняться по-умолчанию), но и любого State вашего кастомного виджета. Все сохраняемые свойства вам предстоит оборачивать в специальные Restorable-контейнеры, вручную регистрировать их в RestorationMixin.
Выглядит так, что большинство разработчиков будет просто этим пренебрегать. Посмотрим: может быть, скоро кто-то придумает, как оптимизировать поддержку сохранения состояния, так как сама идея крайне правильная и нужная.
Предварительная версия: плавная прокрутка для непревзойдённых частот ввода и отображения
Работая с нашими внутренними партнёрами из Google, команда Flutter значительно улучшила производительность прокрутки, когда частота ввода и отображения не совпадают. Например, вход Pixel 4 работает с частотой 120 Гц, а дисплей работает с частотой 90 Гц. Это несоответствие может привести к снижению производительности при прокрутке. С новым флагом
resamplingEnabled
вы можете решить эту проблему:void main() {
GestureBinding.instance.resamplingEnabled = true;
run(MyApp());
}
В зависимости от рассматриваемых частотных несоответствий, вы можете увидеть до 97% меньше задержек при прокрутке, если включите этот флаг. В будущих сборках мы планируем включить этот флаг по умолчанию.
Новый унифицированный инструмент разработчика Dart
Как всегда, обновление Flutter касается не только движка и фреймворка, но и инструментов. Flutter 1.22 включает новую версию Dart (2.10), а также новый инструмент командной строки
dart
, который также может оказаться полезным.Исторически у Dart было много небольших инструментов для разработчиков (таких как
dartfmt
для форматирования и dartanalyzer
для анализа кода). В Dart 2.10 есть унифицированный инструмент разработки dart
, очень похожий на инструмент flutter
.Начиная с Flutter 1.22 SDK, в папке
<flutter-sdk>/bin
(которая, вероятно, у вас есть в yourPATH
) содержатся команды flutter
и dart
. Для получения дополнительной информации см. Сообщение в блоге Dart 2.10.Инструмент анализа размера приложения
Инструменты, выпущенные как часть Flutter 1.22, включают новую утилиту анализа размера сборки. Этот инструмент помогает диагностировать, не раздувается ли размер вашего приложения с течением времени.
Вы можете использовать этот инструмент, чтобы собирать данные для анализа. Передайте флаг
--analysis-size
любой из следующих команд:flutter build apk
flutter build appbundle
flutter build ios
flutter build linux
flutter build macos
flutter build windows
Использование этого флага при построении выходного артефакта Flutter выводит сводку о размере и составе артефакта. Она включает нативный код, ресурсы и даже разбивку на уровне пакета скомпилированного кода Dart.
Пример разбивки релизного APK Flutter Gallery
Эта сводка полезна, чтобы быстро проанализировать размер сборки и понять, из-за чего она слишком большая. Кроме того, собранные данные также доступны в виде файла JSON, который можно посмотреть в Dart DevTools, что позволяет дополнительно исследовать содержимое приложения, выявлять проблемы с размером и видеть изменения между двумя разными файлами JSON, следуя инструкциям на flutter.dev. После загрузки файла JSON у вас будет интерфейс, в котором отображается древовидная карта размера вашего приложения.
Пример разбивки APK в Dart DevTools
Документации по инструменту анализа размера приложения на сайте flutter.dev
Комментарий
То, что давно умеет Android Studio сама по себе, теперь можно анализировать и через Dev Tools. Реализовано это даже более гибко. Теперь вы можете деплоить отчёты в Json прям на CI и мониторить изменения размера сборки в динамике.
Предварительная версия: обновленная страница Network в DevTools
Еще одна предварительная функция DevTools в этом выпуске: теперь во вкладке Network отображается body запроса.
Чтобы включить эту функцию, убедитесь, что вы находитесь на dev-канале Flutter через
flutter channel dev
и flutter channel upgrade
.Кроме того, для приложений с большим объёмом сетевого трафика мы предусмотрели возможность поиска и фильтрации.
Документацию по вкладке Network ищите в разделе Использование Network View на flutter.dev.
Вкладка Hosted DevTools Inspector в IntelliJ
Уже некоторое время мы поддерживаем две копии некоторых наших инструментов Flutter: например, панель Inspector в IntelliJ и вкладку Inspector в Dart DevTools. Это замедляет нашу работу: нам нужно поддерживать две кодовые базы. Кроме того, некоторые функции еще не вошли в плагин IntelliJ — например, Layout Explorer. Чтобы решить эти проблемы, мы включили возможность размещения вкладки Inspector из Dart DevTools непосредственно внутри IntelliJ.
Чтобы включить эту опцию, перейдите в Preferences > Languages & Frameworks > Flutter > Enable embedded DevTools inspector.
Комментарий
Ещё одно маленькое, но очень важное изменение. В одном из выпусков Flutter Dev Podcast мы даже посвятили несколько минут обсуждению разницы в инструментах разработчика в Android Studio и VS Code.
Как оказалось, это действительно два разных проекта с независимыми кодовыми базами и это… странно. Со временем каждая из этих разработок обрастала своими фичами, всё больше и больше отличаясь от своего аналога для друго IDE. Теперь этому будет положен конец. Предсказываю, что встроенные инструменты скоро исчезнут из плагина для Android Studio. А пока привыкайте к новой интеграции.
Улучшенный вывод логов в Visual Studio Code
Обычное действие, с которым сталкиваются все разработчики Flutter, — переход из стектрейсов ошибок в терминале к месту в исходном коде, где произошла ошибка. В самом последнем выпуске расширения Flutter для Visual Studio Code эти ссылки теперь парсятся правильно: по ним можно кликнуть и перейти в нужное место кода, в котором произошло падение.
Это кажется мелочью, но первоначальные отзывы об этой функции уже очень положительные.
Как всегда, здесь слишком много списка изменений инструментов, но я рекомендую изучить следующие анонсы:
- Dart DevTools — 0.9.0
- Dart DevTools — 0.9.1
- Dart DevTools — 0.9.3
- Выпуск плагина Flutter IntelliJ M48.1
- Выпуск плагина Flutter IntelliJ M49
- Выпуск плагина Flutter IntelliJ M50
- Расширения VS Code v3.14.0
- Расширения VS Code v3.15.0
В центре внимания клиентов: EasyA
EasyA — это приложение по подписке: школьники занимаются с блестящим репетиторам через обмен мгновенными сообщениями. Приложение написано на Flutter. Недавно Apple отметила его как приложение дня.
«Когда в начале этого года школы стали переходить на дистанционку, у нас была задача быстро запустить приложение, чтобы помочь ученикам. Благодаря высокой скорости разработки на Flutter мы смогли сделать приложение как для iOS, так и для Android. И успели их опубликовать в сторах — как раз к началу локдауна! В обычных условиях это было бы практически невозможно. Но поскольку Flutter позволяет нам работать со всеми тремя платформами одновременно, мы смогли эффективно переиспользовать код. Наша небольшая команда разработчиков работала на полную».
Фил Квок, соучредитель EasyA
Критические изменения
Как всегда, мы стараемся свести количество критических изменений к минимуму. Вот список из версии Flutter 1.22:
- 56413 Запретить viewport.showOnScreen прокручивать область просмотра, если указанный Rect уже отображается.
- 62395 [gen_l10n] Генерация синтетических пакетов по умолчанию.
- 62588 Build routes even less.
Стабильная версия Flutter 1.22, возможно, вышла очень быстро после релиза 1.20, но в ней так много хорошего, что здесь мы не смогли упомянуть всё. Надеемся, что этот релиз поможет вам создавать потрясающие приложения для iOS и Android, и нам не терпится увидеть, что появится в сторах! Спасибо за вашу поддержку: мы создаём Flutter для вас.