Flutter 2.2: что нового?

Этот релиз сосредоточен на оптимизации и совершенствовании функци, включая улучшение работы на iOS, отложенные компоненты Android (deferred components), обновленный сервис-воркер для Flutter web и многое другое!

Перевод статьи What’s new in Flutter 2.2

19 мая Flutter версии 2.2 стал доступен для всех пользователей и разработчиков. Обновиться до этого релиза можно переключившись на стабильный канал и обновив вашу нынешнюю версию Flutter, или же перейдя в flutter.dev/docs/get-started загрузив новую версию.

Хоть с релиза Flutter 2 прошло всего пара месяцев, в релизе 2.2 мы добавили множество улучшений. Релиз закрывает 3105 проблем по всему фреймворку, движку и репозиторию плагинов. Отдельную благодарность выражаем всем участникам сообщества, помогавшим сделать Flutter 2.2 стабильным каналом и вносившим свои изменения и предложения — без вашей помощи мы бы не справились.

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

Flutter 2.2 обновления стабильной версии

Этот выпуск покрывает огромное количество улучшений версии Flutter 2, в том числе обновления для Android, iOS и WEB, новые иконки Material, обновление обработки текста, поведения ползунка прокрутки , поддержку курсора мышки для виджета TextSpan и новые рекомендации по поддержке нескольких типов платформ из единой базы исходного кода. Все эти функции уже доступны в стабильной версии и готовы для использования вами в разработке приложений. Кроме того, они все встроены в новый релиз Dart.

Dart 2.13

Flutter 2.2 поставляется вместе с релизом Dart 2.13. Помимо прочего, этот выпуск содержит новый функционал псевдонимов (алиасов) типов, который позволяет давать псевдонимы типам как и функциям:

// Type alias for functions (existing)
typedef ValueChanged<T> = void Function(T value);

// Type alias for classes (new!)
typedef StringList = List<String>;

// Rename classes in a non-breaking way (new!)
@Deprecated("Use NewClassName instead")
typedef OldClassName<T> = NewClassName<T>;

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

Обновление Flutter web

В этом релизе была усовершенствованна работа с веб-платформой. Для начала, мы оптимизировали кэширование при помощи нового механизма загрузки сервис-воркеров, а также исправили двойную загрузку main.dart.js. В предыдущих версиях Flutter web сервис-воркер загружал обновления для вашего приложения в фоновом режиме, предоставляя пользователю доступ к устаревшей версии. После загрузки обновления пользователь не увидит этих изменений, пока не обновит страницу браузера пару раз. Начиная с Flutter 2.2, когда новый сервис-воркер обнаруживает изменение, пользователю придется дождаться окончания загрузки обновления, чтобы использовать приложение, но затем эти обновления будут видны, не требуя повторного обновления страницы вручную.

Включение этого изменения требует, чтобы вы перегенерили index.html вашего приложения. Для этого сохраните все изменения, удалите файл index.html, а затем запустите flutter create . в репозитории проекта.

Также получили улучшения и оба веб-рендерера. Для HTML мы добавили поддержку расширенных типографических свойств (font features) для настойки FontFeature и использования API холста для рендера текста, чтобы он находился в правильном месте. Для HTML и CanvasKit мы добавили поддержку масок шейдеров и computeLineMetrics, устраняя пробелы в равенстве между мобильными и веб-приложениями Flutter. К примеру, разработчики теперь могут использовать маски непрозрачности, чтобы выполнять плавные переходы с шейдерными масками, и использовать computeLineMetrics, как для мобильных приложений.

Для Flutter web, как и для всего Flutter вообще, универсальный доступ является нашим главным приоритетом. По задумке, Flutter реализует доступность специальных возможностей, создавая дерево SemanticsNode. Как только пользователь веб-приложения Flutter включает специальные возможности, фреймворк генерирует DOM-дерево, параллельное DOM-дереву RenderObject, и транслирует семантические свойства для Aira. В этом релизе мы усовершенствовали положение семантического узла, чтобы сократить разрыв между мобильными и настольными веб-приложениями при использовании преобразований, что означает, что фокус-бокс должен правильно отображаться над элементами, когда виджеты стилизованы с преобразованиями. Вот видео Виктора Царана (Victor Tsaran), который возглавляет программу специальных возможностей для Material Design, используя VoiceOver с приложением Flutter Gallery:

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

Чтобы включить эту функцию в вашем собственном веб-приложении, запустите код:

$ flutter run -d chrome --profile --dart-define=FLUTTER_WEB_DEBUG_SHOW_SEMANTICS=true

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

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

И последнее, но не менее важное: последняя версия Flutter DevTools теперь поддерживает Layout Explorer для веб-приложений Flutter.

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

Переходы между страницами на iOS и инкрементальные установки

Для iOS в этом релизе мы сделали переходы в Cupertino между страницами более плавными, сократив время рендеринга фреймов анимации на 75%, и даже больше на более бюджетных девайсах. Мы стремимся к совершенствованию не только конечного продукта; но и процесса его разработки.

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

Flutter для создания платформенно-адаптивных приложений

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

И, наконец, в качестве примеров приложений, написанных для нескольких платформ в соответствии с этими принципами, мы рекомендуем приложения Flokk и Flutter Folio от gSkinner. Вы можете загрузить исходный код Flokk и Folio, а также загрузить Flokk и Folio из различных магазинов приложений или запустить их прямо в браузере. Еще один отличный пример — приложение, используемое для создания самого руководства:

UX-части руководства по адаптивным приложениям платформы Flutter основаны на новом руководстве для больших экранов. Это новое руководство от группы Material включает переработку нескольких основных статей по макету, а также обновления нескольких компонентов и обновленный Design Kit для больших экранов.

Целью Flutter всегда было создание приложений, которые не просто работают на нескольких платформах; приложения должны работать идеально на всех целевых платформах. У Flutter есть поддержка, необходимая не только для выпуска вашего приложения на несколько платформ, но и для адаптации ваших приложений к размеру экрана, режимам ввода и идиомам каждой из этих платформ.

Еще больше иконок Material

Также с этим релизом идет целых два PR, добавляющих новые иконки Material, включая иконки для Dash.

Обновление увеличивают общее количество значков Material для ваших приложений до 7000. Если вам не удается найти значок среди всего этого количества, вы можете выполнить поиск по категории и имени на fonts.google.com/icons.

Новая вкладка «Flutter» покажет, как использовать найденный значок, также вы можете просто скачать только этот значок для использования в качестве самостоятельного ресурса в вашем приложении. Еще никогда присоединение Dash к вашему Flutter-приложению не было таким простым!

Улучшенная обработка текста

Улучшая Flutter для поддержки особенностей каждой платформы, мы продолжаем осваивать новые области, которые не так важны для мобильных видов устройств, как для настольных ПК. Одна из таких областей — обработка текста. В этом выпуске мы начали рефакторинг того, как мы обрабатываем ввод текста, который включает такие функции, как отмена нажатия клавиши, пока она перемещается по иерархии виджетов, а также возможность полностью настраивать нажатия клавиш, связанные с текстовыми действиями.

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

import 'package:flutter/material.dart';
void main() => runApp(App());
class App extends StatelessWidget {
 @override
 Widget build(BuildContext context) => MaterialApp(
       title: 'Flutter Text Editing Fun',
       home: HomePage(),
     );
}

class HomePage extends StatelessWidget {
 @override
 Widget build(BuildContext context) => Scaffold(
       body: Column(
         children: [
           TextField(),
           OutlinedButton(onPressed: () {}, child: const Text('Press Me')),
         ],
       ),
     );
}

Настраиваемые текстовые действия позволяют выполнять такие действия, как особая обработка клавиши Enter в TextField; например, вы можете инициировать отправку сообщения в клиенте чата, при этом позволяя вставлять новую строку с помощью Ctrl + Enter. Эти же текстовые действия позволяют самому Flutter предоставлять различные сочетания клавиш, чтобы соответствовать поведению редактирования текста в самой ОС устройства, например, Ctrl + C в Windows и Linux, а Cmd + C в macOS.

Следующий пример переопределяет действие стрелки влево по умолчанию и предоставляет новое действие для клавиш backspace и delete:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
 @override
 Widget build(BuildContext context) => MaterialApp(
       title: 'Flutter TextField Key Binding Demo',
       home: Scaffold(body: UnforgivingTextField()),
     );
}

/// A text field that clears itself if the user tries to back up or correct
/// something.
class UnforgivingTextField extends StatefulWidget {
 @override
 State<UnforgivingTextField> createState() => _UnforgivingTextFieldState();
}

class _UnforgivingTextFieldState extends State<UnforgivingTextField> {
 // The text editing controller used to clear the text field.
 late TextEditingController controller;

 @override
 void initState() {
   super.initState();
   controller = TextEditingController();
 }

 @override
 Widget build(BuildContext context) => Shortcuts(
       shortcuts: <LogicalKeySet, Intent>{
         // This overrides the left arrow key binding that the text field normally
         // has in order to move the cursor back by a character. The default is
         // created by the MaterialApp, which has a DefaultTextEditingShortcuts
         // widget in it.
         LogicalKeySet(LogicalKeyboardKey.arrowLeft): const ClearIntent(),

         // This binds the delete and backspace keys to also clear the text field.
         // You can bind any key, not just those already bound in
         // DefaultTextEditingShortcuts.
         LogicalKeySet(LogicalKeyboardKey.delete): const ClearIntent(),
         LogicalKeySet(LogicalKeyboardKey.backspace): const ClearIntent(),
       },
       child: Actions(
         actions: <Type, Action<Intent>>{
           // This binds the intent that indicates clearing a text field to the
           // action that does the clearing.
           ClearIntent: ClearAction(controller: controller),
         },
         child: Center(child: TextField(controller: controller)),
       ),
     );
}

/// An intent that is bound to ClearAction.
class ClearIntent extends Intent {
 const ClearIntent();
}

/// An action that is bound to ClearIntent that clears the TextEditingController
/// passed to it.
class ClearAction extends Action<ClearIntent> {
 ClearAction({required this.controller});

 final TextEditingController controller;

 @override
 Object? invoke(covariant ClearIntent intent) {
   controller.clear();
 }
}

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

Автоматическая полоса прокрутки

Поскольку мы постоянно стремимся к тому, чтобы приложения Flutter являлись лучшими на каждой платформе, мы решили еще раз обратиться к полосам прокрутки. Когда дело доходит до фактического отображения полосы прокрутки, и Android, и iOS одинаковы; по умолчанию они не отображаются. С другой стороны, для настольного приложения полоса прокрутки обычно отображается автоматически, когда содержимое больше контейнера, что требует добавления родительского виджета Scrollbar. Чтобы обеспечить правильное поведение на мобильном устройстве или компьютере, в этом выпуске при необходимости автоматически добавляется полоса прокрутки Scrollbar.

Рассмотрим следующий код без полосы прокрутки:

import 'package:flutter/material.dart';

void main() => runApp(App());

class App extends StatelessWidget {
 @override
 Widget build(BuildContext context) => MaterialApp(
       title: 'Automatic Scrollbars',
       home: HomePage(),
     );
}

class HomePage extends StatelessWidget {
 @override
 Widget build(BuildContext context) => Scaffold(
       body: ListView.builder(
         itemCount: 100,
         itemBuilder: (context, index) => Text('Item $index'),
       ),
     );
}

При запуске приложения на персональном компьютере, появляется полоса прокрутки:

Если вас не устраивает то, как выглядит полоса или то, что она постоянно отображается, вы можете настроить ScrollBarTheme. Если не устраивает ее дефолтное поведение, вы можете настроить его в ScrollBehavior. Дополнительную информацию о новом поведении полосы прокрутки по умолчанию можно найти в документации на flutter.dev.

Курсоры мыши поверх фрагментов текста

В предыдущих версиях Flutter вы могли добавить курсор в виде руки (как индикатор того, что на область можно нажать) поверх любого виджета. На самом деле, в большинстве случаев Flutter сам добавляет курсоры, например, поверх всех кнопок появляется курсор-рука. Однако, если вы хотели запустить длинный текст с множеством текстовых фреймов и с ссылками, вам не повезло: TextSpan не является Widget, и следовательно курсор не мог появиться в той области. Теперь же, если у вас у вас есть TextSpan с распознавателем жестов, соответствующий курсор мыши автоматически появляется:

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart' as urlLauncher;

void main() => runApp(App());

class App extends StatelessWidget {
 static const title = 'Flutter App';
 @override
 Widget build(BuildContext context) => MaterialApp(
       title: title,
       home: HomePage(),
     );
}

class HomePage extends StatelessWidget {
 @override
 Widget build(BuildContext context) => Scaffold(
       appBar: AppBar(title: Text(App.title)),
       body: Center(
         child: RichText(
           text: TextSpan(
             style: TextStyle(fontSize: 48),
             children: [
               TextSpan(
                 text: 'This is not a link, ',
                 style: TextStyle(color: Colors.black),
               ),
               TextSpan(
                 text: 'but this is',
                 style: TextStyle(color: Colors.blue),
                 recognizer: TapGestureRecognizer()
                   ..onTap = () {
                     urlLauncher.launch('https://flutter.dev');
                   },
               ),
             ],
           ),
         ),
       ),
     );
}

Теперь, при наведении на ссылку в тексте, появляется соответствующий вид курсора мыши:

Также TextSpan теперь поддерживает onEnter и onExit вместе с mouseCursor. Эти изменения могут показаться совсем маленькими, однако каждое такое маленькое улучшение приводит к совершенствованию приложений Flutter.

Flutter 2.2 новые предварительные функции

Кроме уже действующих изменений, Flutter 2.2 обладает рядом функций в предварительной версии, включая улучшения производительности компилятора шейдеров iOS, поддержку отложенных компонентов Android, обновления десктопного Flutter и поддержку устройств ARM64 Linux от Sony.

Превью: улучшения компиляции шейдеров на iOS

В терминах рендеринга графики «шейдер» — это программа, которая компилируется и запускается на графическом процессоре, доступном на устройстве конечного пользователя. Flutter использует шейдеры в базовой графической библиотеке Skia с момента своего создания для обеспечения собственной производительности в собственных высококачественных графических эффектах с цветами, тенями, анимацией и т. д. Благодаря гибкости API-интерфейсов Flutter шейдеры создаются и компилируются точно в срок, синхронно с рабочими нагрузками кадров, которые в них нуждаются. Когда время компиляции шейдеров выходит за рамки бюджета кадра, результат воспринимается пользователями как «зависание».

Чтобы избежать зависания, Flutter предоставил возможность кэширования шейдеров при первом прогоне, затем кэш пакетируется и объединяется с приложением и компилируется перед первым фреймом при запуске Flutter Engine. Это означает, что предварительно скомпилированные шейдеры не нужно компилировать во время рабочей нагрузки кадра, что не вызывает зависания. Однако изначально Skia реализовала эту функцию только для OpenGL.

Итак, когда мы включили графику Metal по умолчанию на iOS в ответ на отказ Apple от OpenGL, наблюдалось увеличение наихудшего времени кадра, измеренного нашими тестами, и увеличение количества пользовательских отчетов о зависании. Наши собственные измерения показали, что эти отчеты часто были связаны с увеличением времени компиляции шейдеров, увеличением количества шейдеров, созданных Skia для графики Metal, и невозможностью кэширования скомпилированных шейдеров во время прогона, так что зависание сохранялось после первого прогона приложения.

Так что до этого релиза единственным путем избегания этого зависания на iOS было упрощение анимации и сцен.

Однако прямо сейчас на канале разработчиков есть предварительный просмотр новой поддержки в Skia для разогрева шейдеров для Metal. Через Skia Flutter теперь компилирует объединенные шейдеры до начала рабочей загрузки первого кадра.

Однако, это решение имеет свои особенности:

  • Skia по-прежнему генерирует больше шейдеров для Metal, чем для OpenGL.
  • Окончательная компиляция шейдера в машинный код по-прежнему происходит синхронно с рабочей нагрузкой кадра, но это все же быстрее, чем генерация и компиляция всего шейдера как часть времени рендеринга кадра.
  • Полученный машинный код кэшируется после первого запуска приложения до перезагрузки устройства.

Если вы заинтересованы в использовании этой функции, то можете ознакомиться с подробной инструкцией на flutter.dev.

Однако это еще не все. Как на Android, так и на iOS эта реализация имеет несколько недостатков:

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

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

Наш прогресс вы можете отслеживать в этом проекте.

Отложенные компоненты Andriod (deferred components)

В этом релизе для Android используется функция раздельной компиляции AOT Dart, позволяющая приложениям Flutter загружать модули, содержащие заранее скомпилированный код и ресурсы, во время выполнения. Мы называем каждый из этих устанавливаемых частей отложенным компонентом. Если отложить загрузку кода и ресурсов только при необходимости, размер начальной установки можно значительно уменьшиться. Например, мы реализовали версию Flutter Gallery, в которой все исследования и демонстрации были отложены, и размер начальной установки уменьшился на 46%.

При сборке с включенными отложенными компонентами Dart компилирует код, импортированный исключительно с ключевым словом deferred, в отдельные общие библиотеки, которые упаковываются в отложенные компоненты вместе с ресурсами.

Отложенные компоненты в настоящее время доступны только на Android, и эта функция предлагается в качестве предварительной версии. Узнайте, как реализовать отложенные компоненты на новой Deferred componentsна flutter.dev. Эта страница также ссылается на страницу вики Flutter, которая содержит подробное описание того, как работает эта функция. Пожалуйста, регистрируйте проблемы в системе отслеживания Flutter.

Flutter Windows UWP alpha

Еще одно обновление для Flutter в этом выпуске предназначено для пользователей настольных компьютеров; поддержка Windows UWP перешла на альфа-канал в канале разработки (после стабильной версии 2.2). UWP позволяет переносить приложения Flutter на устройства, на которых не работают стандартные приложения Windows, включая Xbox. Чтобы опробовать , сначала необходимо настроить необходимые компоненты UWP. Затем переключитесь на канал разработчика и включите поддержку UWP:

$ flutter channel dev
$ flutter upgrade
$ flutter config — enable-windows-uwp-desktop

После включения создание приложения Flutter включает новую папку winuwp, которая позволяет создавать и запускать приложение в контейнере UWP:

$ flutter create uwp_fun
$ cd uwp_fun
$ flutter pub get
$ flutter run -d winuwp

Поскольку вы создаете приложение Windows UWP, которое работает в среде песочницы в Windows, вам нужно будет открыть в брандмауэре доступ приложению на локальном хосте во время разработки, чтобы включить такие функции, как горячая перезагрузка и контрольные точки отладчика. Вы можете сделать это с помощью команды checknetisolation, следуя инструкциям на странице документации Flutter для персонального компьютера. Как только вы это сделаете, вы сможете увидеть, как ваше приложение Flutter работает как приложение UWP в Windows.

 

 

 

 

 

Меню