关于android:Flutter-122-正式版发布

2次阅读

共计 9139 个字符,预计需要花费 23 分钟才能阅读完成。

继 9 月 23 号公布 Flutter Windows 内测版 之后刚过几天,Flutter 官网在昨夜凌晨正式公布了 Flutter 1.22。

本次版本的降级又带来了新一轮的性能公布,性能改良和问题修复。恰逢挪动平台新版本(iOS 14/Android 11)的公布季,此次的版本更新保障了 Flutter 利用在 Android 11 和 iOS 14 上的兼容性,面向 iOS 14,本次更新包含了对 Xcode 12,新 Icon 的更新以及 App Clips 性能的预览。对于 Android 11,此次更新包含了多种屏幕适配以及软键盘动画的流畅性优化。

间隔上个版本公布刚刚两个月,此次版本的更新最为疾速,但品质却仍然没有降落,Github 数据显示此次更新共解决了 3,024 个 issue,合并了 197 个贡献者的 1,944 个 PR,而在这些贡献者中有 114 位(58%)来自社区的反对,他们共提交了 271 个 PR,奉献量最大的是 a14n,共提交了 20 个 PR。

除了对新平台的全力支持外,Flutter 的本次更新也迎来了很多值得分享的话题,包含社区探讨最为热烈的 Android 状态复原,新的 Material 按钮组件以及国际化和本地化反对与热重载并用等性能。此次更新也包含了全新的导航器(Navigator),稳定版 Platform Views(反对 Google Maps 和 WebView 插件)以及高频率设施下滚动性能的优化,同时,开发工具的更新也迎来了另一番现象。

新平台适配

iOS 14

每次 Android/iOS 等平台推出零碎的新版本时,Flutter 都会进行全面的整改来避免出现不兼容的景象。因而,iOS 14 的公布也推动了 Flutter 的新一轮更新,次要包含如下几点:

  • XCode 12 仅反对 iOS 9.0 以上的版本,因而 Flutter 我的项目已将默认反对的版本从 8.0 更新到了 9.0。
  • Flutter 1.22 修复了在 iOS 14 零碎下的的闪退和字体渲染的问题。
  • 自 Flutter 1.20.4 起也已齐全解决了部署到真机设备上呈现的各种问题。
  • 当应用程序拜访其剪贴板时,会导致 Flutter 应用程序弹出谬误告诉,该问题也已在 1.20.4 中解决。
  • iOS 14 上存在禁止在设施上运行 debug 应用程序的限度(理论开发调试过程除外)。
  • 思考到网络安全性的问题,本地调试的 Flutter 应用程序会在 iOS 14 上显示一次性确认对话框(仅开发期间)。

如果你的 Flutter 应用程序须要运行在 iOS 14 零碎上,咱们强烈建议你将 Flutter 版本更新到 1.22 并立刻部署到 App Store 中,这样能够确保你的 iOS 14 用户获得最佳体验。

无关 Flutter 如何适配 iOS 14 的更多信息,包含如何增加到原生利用、deep linking 等问题,能够参阅官网 iOS 14 文档。咱们的指标始终是心愿开发者们能齐全脱离所有工具和 SDK 的更新而者专一于利用自身的业务逻辑,这就要求咱们须要充沛反对 iOS 14 的各种新的个性。

本次,咱们就针对 iOS 新公布的 SF Symbols 字体做了更新反对,对 cupertino_icon 库做了一系列的更新,当初只须要将 cupertino_icon 更新到最新的 1.0 版本,就能主动将 CupertinoIcons 映射成新款式的图标,Flutter 1.22 后,CupertinoIcons 也额定提供了 900 个新图标。


开发者能够在 iOS 14 上 尝试应用 Flutter 的另一个性能就是 App Clips(轻利用),这是 iOS 14 推出的一项新性能,它反对 10MB 以下轻量级应用程序的疾速,免装置关上,而在 Flutter 1.22 版之后的版本,咱们就能够试一下 Flutter 在 iOS 上反对的 App Clip 性能了。

Android 11

Flutter 的此次更新也同样同步了本月公布的 Android 11。为了反对 Android 11 中引入的两个新性能,Flutter 框架层和引擎层都已做了相应的更新。首先,Flutter 当初曾经反对多种全新 Android 屏幕的适配,如下图:

通过应用 MediaQuerySafeArea 这两个组件,开发者就能够确保将展现的 UI 和交互式组件搁置在设施显示屏的无障碍区域中。另外,目前咱们须要尽量避免在瀑布屏边缘区域应用手势检测器,因为这些手势检测器可能会导致意外触摸。其次,显示软件键盘时的动画也曾经与 Android 11 同步。


此前,Flutter 始终存在 #19279 这个问题,其中零碎键盘的显示 / 暗藏动画与 Flutter 并不同步,这个问题也曾经在此次更新中被修复。
对于 Android 嵌入 API 的正文。去年,Flutter 1.12 推出了一套全新的 Flutter 插件 API,咱们开发了 v2 API 使开发者们可能更好的将 Flutter 嵌入到已有的原生利用中。据咱们统计,到目前为止曾经有超过 80% 的 Android 插件应用了新的 Android API 了,因而,从本次公布 1.22 开后,咱们便不再保护旧的 v1 API。

如果你仍在应用 Android v1 API,可能会导致如下问题:

  • 无奈应用新开发的插件
  • Flutter 工具的 —no-enable-android-embedding-v2config 标记已被默认删除仍在应用 v1 API 的旧版应用程序在构建期间会显示弃用正告,并指向反对新的 Android 插件 API 文档

同时,如果你依然有基于 v1 Android API 的 Flutter 应用程序,它尽管可能失常运行,然而很可能会应用遇到仅反对 v2 API 的新插件,而这些插件不能被 v1 Android API 应用。

全新的 Button 组件

之前的版本中,Flutter 曾经有了一套齐备的按钮组件,但应用起来却很麻烦,Material 标准也减少了多个新款式的按钮。所以,为了使 Flutter 放弃与 Material 的同步,咱们正式地发表 Flutter 1.22 将引入全新的“Button”按钮。


新的 Button 组件的命名标准也与 Material Design 设计准则,如下图所示。

DartPad 上有一个很好的示例。另外,旧的组件如 FlatButton,OutlineButton,RaisedButton,ButtonBar,ButtonBarTheme 也并不会被弃用,开发能够依照需要混合应用旧按钮与新按钮。

全新的国际化和本地化的反对

自 Flutter 公布以来,曾经为利用提供了较好的国际化(i18n)和本地化(l10n)所需的外围性能的反对,而在此次的新版本中,咱们也将该性能的最佳实际纳入了咱们的开发工具中,并且,在增加新的 l10n 信息时启用了热重装反对来间接更新应用程序。


如果你想理解无关 Flutter l10n 的更多信息,包含本地化音讯,带有参数,日期,数字和货币的音讯,请参见 Flutter Internationalization 用户指南。
此外,如果你对 i18n 和 l10n 感兴趣,你可能还对那些字符串不蕴含在一般 ASCII 字符的字符串,例如 Unicode 和 emoji 的问题比拟惯性。本次,Dart 团队也公布了 characters 软件包能够帮忙开发人员解决 Unicode(扩大)字符簇。该库能够帮忙开发者们解决诸如如何正确地将字符串(如“A ???????? text in English”)缩写为前 15 个字符的问题,应用 String 类,该字符串能够缩写为“A ???????? text in”,它仅是 12 个用户可感知的字符。另一方面,应用 characters 也能够生成“A ???????? text in Eng”的正确缩写。

此 PR 应用 characters 完满的解决了这些简单的字符,例如,当 TextField 带有最大长度 maxLength 限度时,像 ????‍????‍???? 这样的字符当初能够正确地算作单个字符,另外,此 PR,在 Flutter 所在的我的项目中,字符包均可主动在我的项目中应用,而无需手动增加。心愿这使得解决来自所有语言环境的各种字符串变得更加容易。无关 character 包的更多详细信息,请查看文章正确实现 Dart 字符串操作。

Google Maps 和 WebView 插件

Flutter 团队通常会通过认真思考后才会将某些标签标记为“production ready”,在此之前,咱们通常都会对其进行了全面测试。对于 google_maps_flutter 和 webview_flutter 这两个插件底层都是应用 Platform Views 实现,从而容许将 Android 和 iOS 的原生 UI 组件嵌入在 Flutter 应用程序中。在此次的 Flutter 版本中,咱们怅然发表,咱们曾经对框架层进行了强化,齐全可能将这两个插件都申明为可投入生产(即“production ready”)。


在 Flutter 1.22 中,咱们增加了一个代替的 Platform Views 实现,该实现修复了所有已知的键盘以及 Android 视图的可拜访性问题。此外,它还实用于 19 级及以上的 Android API(以前要求 20 级)。咱们还对 iOS 上的线程进行了改良,使平台视图更高效,更牢靠(并且不再须要你将 io.flutter.embedded_views_preview 标记增加到 iOS 中 Info.plist)。

该 webview_flutter 插件反对新的 Android Platform Views 模式,但以后须要手动启用。一旦在更宽泛的社区中失去更多应用,咱们将默认在未来的版本中启用它。
Google Maps 和 WebView 插件曾经从 Platform Views 的改良中受害。如果你想应用平台视图在 iOS 或 Android 上嵌入本人的原生 UI 组件,能够参阅如何 Hosting native Android and iOS views in your Flutter app with Platform Views。

Navigator 2.0

如果你之前在 Flutter 应用程序中应用过 Navigator,则可能曾经留神到外围数据结构(用户正在浏览的页面路由堆)对你是不可见的。每次要进行治理时,须要调用 Navigator.pop() 或 Navigator.push()。例如,假如你要在主页上显示一系列组件,并容许用户点击一个组件以进入该色彩的详细信息页面,如下图。


咱们能够应用上面这种形式实现这两个简略的 UI 页面,代码如下。

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 中的 build 办法中显式地创立 Containers 列表不同,该路由栈并不可见,因而很难治理一些非凡状况,如解决由原生嵌入提供的初始路由的 deep linking,或者来自 Web 的 URL 或来自 Android 的 intent,治理同一页面的不同程序之间的嵌套路由也极其艰难。

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 顶部创立一个 ColorScreen 页面。
你能够在 OnPopPage 回调函数中更新返回的状态,例如,如果用户回退,则示意他们“勾销抉择”了以后色彩,从而 _selectedColor = null 示意不再心愿显示该页面。
Navigator 2.0 看起来像 Flutter 的其余部分,那正是她的用意,它是申明性的,与 Navigator 1.0 势在必行,这个想法是要在导航和 Flutter 的其余部分之间对立模型,同时解决许多问题并增加性能。实际上,这个小例子简直还不波及 Navigator 2.0 的内容。无关详细信息,举荐浏览 Declarative navigation and routing in Flutter。

另外,Navigator 1.0 仍然能够持续应用,短期内也不会生效,如果你曾经喜爱这种路由模式,齐全能够持续应用它。然而,如果你尝试应用 Navigator 2.0,咱们认为你会喜爱的。

预览性能

Android 的状态还原

在此次的新版本中还可能试用一些新性能,如对 Android 的状态还原的 反对。这是咱们在 Github 上最受欢迎的性能之一,领有 217 个点赞!

思考到读者们可能不相熟状态还原这个需要。挪动操作系统可能会杀死后盾的应用程序,以回收前台应用程序的资源。产生这种状况时,操作系统会告诉该利用曾经被终止,这样开发者就能够疾速保留以后 UI 状态,以便在用户再次回到该利用时能够将其复原。如果该功能完善,就能够为用户提供无缝的体验了,同时也能够更好地利用设备的资源。目前,Flutter 还并不反对状态还原,如果没有框架层的反对,也很难自行地进行状态地还原,因而,在 Flutter 1.22 中咱们也发表推出该性能的根底实现,欠缺的话还须要进行优化。

例如,上面是一个用于复原默认 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),
    );
}

简要地说,每个组件都有一个存储桶(storage bucket),RestorationMixin 应用惟一的 ID 向其注册。通过应用一种 RestorableProperty 类型(如这里的 RestorableInt)来存储特定于 UI 数据,并应用状态复原性能注册该数据,该数据将在 Android 终止该应用程序之前主动保留,并在其再失常运行时进行复原。就是这样,Restoration* 能够保留任何类型的数据,如 RestorableInt,RestorableString 和 RestorableTextEditingController(等等)都将能够被复原。

如果零碎内置没有涵盖你要还原的数据类型,也能够通过 RestorableProperty<T> 创立本人的类型。

为了实现状态复原的自动测试,咱们也向 WidgetTester 减少了全新的 restartAndRestore API。如果想要手动测试,最简略的办法就是在 Android 设施上关上曾经启用状态复原的 Flutter 利用,在 Android 开发人员设置中启用“不要保留流动”(如下图),而后运行 Flutter 利用,将其置于后盾,之后再返回。此时,Android 零碎就会先终止再复原你的应用程序了,你能够查看所有是否按预期工作。


尽管咱们曾经推出了状态复原的预览版,但还有很多其余的工作要做。例如,状态复原不仅须要实用于 Android,iOS 应用程序也该当及时同步。此外,咱们也正着手优化本人的内置组件,以在复原过程中默认放弃其状态。咱们曾经在 ListView 和 SingleChildScrollView(记住用户的滚动地位)和 TextFields(复原他们输出的文本)类中提供了该性能反对,咱们也正打算将其扩大到其余组件中。

然而,因为 navigation(1.0 或 2.0)的起因,该性能目前也才出预览版,,也就是说,你的用户还不能体验该性能,咱们行将会在 Beta 中公布,并在 Flutter 的下一个稳固版本中正式公布。

滚动性能优化

因为存在输出和显示频率不同步的状况,Flutter 团队也与 Google 内核部门单干,极大地提高了页面滚动性能。例如,Pixel 4 输出的运行频率为 120hz,而显示屏的运行频率为 90hz,滚动时,这种不匹配会导致性能降落。应用新的 resamplingEnabled 标记,你就能够解决此问题,如下:

void main() {
  GestureBinding.instance.resamplingEnabled = true;
  run(MyApp());
}

依据所波及的频率差别,启用此标记能够使滚动时的抖动缩小到 97%,当咱们确定这曾经是最好的体验时,咱们曾经打算在当前的版本中默认启用此性能。

应用程式大小剖析工具

作为 Flutter 1.22 的一部分公布的工具包含一个新的输入大小剖析实用程序。此工具可帮忙诊断 Flutter,您的利用大小细分是否会随着工夫变动。

您能够通过将 –analyze-size 标记传递给以下任何命令来应用该工具收集剖析所需的数据,如下所示。

  • flutter build apk
  • flutter build appbundle
  • flutter build ios
  • flutter build linux
  • flutter build macos
  • flutter build windows

在构建 Flutter 输入工件时应用此标记将打印工件尺寸和组成的摘要。这包含本机代码,资产,甚至是已编译 Dart 代码的程序包级细分。

此摘要有助于疾速辨认应用程序的程序包大小用法中的热点。此外,收集到的数据还能够作为 JSON 文件应用,供 Dart DevTools 应用,它使您能够依照 flutter.dev 上的阐明进一步浏览应用程序的内容,查明大小问题并查看两个不同 JSON 文件之间的更改。加载 JSON 文件后,您将领有一个界面,该界面为您提供利用大小的树状图。


无关您能够应用“利用大小”工具执行的操作的更多详细信息,请浏览 flutter.dev 上的“应用利用大小工具”文档。

正文完
 0