0%

【文章翻譯】Announcing Flutter 1.22

【文章內容使用 Gemini 1.5 Pro 自動產生】

宣布 Flutter 1.22

我們很高兴地宣布 Flutter 的最新版本,它对 iOS 14 和 Android 11 提供了广泛的支持。Flutter 1.22 在以前版本的基础上构建,让开发者能够从单一代码库构建快速、美观的跨平台用户体验。我们的季度稳定版本包含最新的功能、性能改进和错误修复,适合广泛的生产使用。

由于这是新移动操作系统版本的发布季节,因此此版本专注于确保 Android 11 和 iOS 14 与 Flutter 完美配合。对这两个操作系统的更新包括大量幕后工作,以符合最新的 SDK,并确保一切通过我们的全面测试套件。对于 iOS 14,此版本包含对新 Xcode 12、新图标的支持,以及对新 iOS 14 App Clips 功能的预览支持。对于 Android 11,更新支持新的显示切口类型,以及在弹出软键盘时的更流畅动画。

此版本在我们的 1.20 版本发布两个月后发布,因此比大多数版本都要短。即使在这段时间内,我们也关闭了 3,024 个问题,并合并了来自 197 位贡献者的 1,944 个 PR。在这 197 位贡献者中,有 114 位(58%)来自更广泛的社区,他们贡献了 271 个 PR。最大的单一贡献者是 a14n,他再次成为我们的顶级贡献者榜单,贡献了 20 个 PR,其中大多数是作为 Flutter 中支持空安全的工作的一部分完成的(更多相关内容即将推出)。

除了对新移动操作系统版本的支持外,我们还有很多新闻要分享,包括对 Android 最受欢迎功能之一的预览:状态恢复、一个新的 Material 按钮“宇宙”、与热重载配合使用的新国际化和本地化支持、一个新的 Navigator、Platform Views 的稳定版本(Google Maps 和 WebView Plugin 的基础)以及可以在代码中添加的开关,以改善具有高频率显示屏的设备上的滚动效果。我们还提供了一个新的工具来剖析应用大小,并确保您构建的 Plugin 仅支持您想要支持的平台。

针对 iOS 14

每当宣布新版本的移动操作系统时,我们都会对其进行彻底测试,寻找影响 Flutter 及其工具的不兼容性或更改。

在 iOS 14 的情况下,我们对 Flutter 做了一些更改,以确保它按开发者想要的方式工作:

  • Xcode 12 要求 iOS 9.0 或更高版本,因此我们的默认模板将默认值从 8.0 提高到 9.0。
  • iOS 14 特定的崩溃和字体渲染问题已在 Flutter 1.22 中修复。
  • 截至 Flutter 1.20.4,已修复部署到实体设备的问题。
  • 一项新政策,当应用访问其剪贴板时会显示使用通知,导致 Flutter 应用出现虚假通知,这个问题已在 Flutter 1.20.4 中修复。
  • 限制禁止在 iOS 14 设备上运行调试应用,除非作为调试过程的一部分。
  • 针对本地调试的 Flutter 应用的网络安全新政策会导致 iOS 14 显示一次性确认对话框(仅在开发期间,而不是针对已发布的 Flutter 应用)。

底线:如果您要针对 iOS 14 使用 Flutter 应用,我们强烈建议您使用 Flutter 1.22 重新构建它并将其部署到 App Store,以确保您的 iOS 14 用户获得最佳体验。

有关使用 Flutter 针对 iOS 14 的更多详细信息,包括一些 Add-to-App、深层链接和通知注意事项,请参阅 flutter.dev 上的 iOS 14 文档

希望所有这些对工具和 SDK 支持的工作可以让您专注于您关心的编码——利用新的 iOS 14 功能。

其中一项功能是对 iOS 的新 SF Symbols 字体的更新支持,这启发了我们花了一些时间对 cupertino_icon 包 进行刷新。一旦您将 cupertino_icons 依赖项更新到新的 1.0 主要版本,现有的 CupertinoIcons 使用情况将自动映射到新样式。如果您将 cupertino_icons 1.0 与 Flutter 1.22 结合使用,您还可以通过 CupertinoIcons API 访问约 900 个新图标。

您可以在 cupertino_icons 预览页面上查看完整的图标列表,以及 flutter.dev 上的迁移详细信息页面

您可以尝试在 iOS 14 上使用 Flutter 的另一项功能是 App Clips,这是一项新的 iOS 14 功能,支持快速、无需安装的应用执行,可以执行 10MB 以下的应用的轻量级版本。在 Flutter 1.22 版本中,我们对使用 Flutter 构建的 App Clip 目标进行了预览。

由 Flutter 提供支持的 App Clip 体验

有关使用 Flutter 构建 App Clips 的更多详细信息,请查看 flutter.dev 上的文档。您还可以参考这个 简单的示例项目

Android 11

此版本的 Flutter 也与本月推出的 Android 11 版本同步。Flutter 框架和引擎已更新,以支持最新版本的 Android 中引入的两个新功能。

首先,Flutter 现在支持公开 Android 切口、切出部分和瀑布显示边缘的安全内边距。

通过使用 MediaQuerySafeArea API,您可以确保将活跃的 UI 和交互式元素放置在设备显示屏的无障碍区域。此外,您还应避免在容易发生意外触碰的瀑布边缘区域放置手势检测器。

其次,动画与 Android 11 同步,因为它显示了软件键盘。

查看 FAB 的位置动画

问题 #19279 是一个长期存在的问题,即系统键盘显示/隐藏动画与 Flutter 的内边距不同步。这个问题已在 Android 11 中修复。

关于 Android 嵌入 API 的一个说明。在去年的 Flutter 1.12 版本中,我们为 Android 推出了新的 Flutter 引擎和 Flutter Plugin API 集。我们创建了这些 v2 API 以更好地支持我们在 Android 上的 Add-to-App 用户。一年后,超过 80% 的 Android Plugin 使用了新的 Android API。从 1.22 版本开始,我们将弃用旧的 v1 API。

如果您仍在使用 Android v1 API,以下内容与您相关:

  • 新创建的 Plugin 将不再针对 v1 API。
  • Flutter 工具的 -no-enable-android-embedding-v2 配置标志已删除,现在是默认行为。
  • 仍在使用 v1 API 的旧应用将在构建过程中显示一个弃用警告,该警告指向 支持新的 Android Plugin API 的文档

同时,如果您仍然具有基于 v1 Android API 的 Flutter 应用,它将继续工作。但是,您可能会开始遇到仅针对 v2 API 且无法被 v1 Android API 使用的新 Plugin。有关更多详细信息,请参阅 重大更改文档

扩展按钮“宇宙”

一个新的 Material Design 按钮“宇宙”

现有的 Flutter 按钮看起来不错,但可能 难以使用,特别是在您需要自定义主题时。此外,Material 规范已扩展到包含具有新样式的新按钮。

为了让 Flutter 与 Material 指南保持同步,我们很高兴地宣布 Flutter 1.22 中推出了全新的按钮“宇宙”。

与其尝试就地演变现有的按钮类及其主题,此 PR 引入了新的替换按钮 Widget 和主题。除了让我们摆脱演化现有类所必需的后向兼容迷宫外,新名称还使 Flutter 与 Material Design 规范 同步,该规范使用新名称来表示按钮组件。

新主题遵循 Flutter 最近为新的 Material Widget 采用的“规范化”模式。如果您想尝试一个演示,这里有一个很棒的 DartPad 演示。这不是重大更改,因为 FlatButton、OutlineButton、RaisedButton、ButtonBar、ButtonBarTheme 和 ButtonTheme 的语义不会改变。您可以根据自己的喜好混合和匹配旧按钮和新按钮。

新的国际化和本地化支持

从 Flutter 的诞生之日起,Flutter 就提供了应用程序国际化 (i18n) 和本地化 (l10n) 所需的核心功能。但是,在此版本中,我们将对最佳实践的看法融入到我们的工具中,甚至启用热重载支持,以便在您添加新的 l10n 信息时更新您的应用。

如果您希望了解有关 Flutter 对 l10n 支持的更多详细信息,包括本地化消息、带有参数的消息、日期、数字和货币,请 阅读 Flutter 国际化用户指南

此外,如果您对 i18n 和 l10n 感兴趣,那么您可能也对不适合纯 ASCII 字符串的字符(例如 Unicode 和表情符号)感兴趣。最近,Dart 团队发布了 characters 包,它帮助开发者处理 Unicode(扩展)字形群集。此包帮助解决了诸如如何将类似于“A 🇬🇧 text in English”的字符串正确缩短到前 15 个字符的问题。使用 String 类,该缩写将是“A 🇬🇧 text in”,这只有 12 个用户感知字符。另一方面,使用 characters 包会产生正确的缩写“A 🇬🇧 text in Eng”。

通过 此 PR,Flutter 使用 characters 包来正确处理这些复杂的字符。例如,当使用带有 maxLength 限制的 TextField 时,像👨‍👩‍👦这样的字符现在被正确地视为单个字符。此外,通过 此 PR,characters 包在 Flutter 所在的项目中自动可用,无需手动添加它。希望这将使处理来自所有语言环境的所有类型的字符串变得更加容易。有关 characters 包的更多详细信息,请查看这篇文章:如何正确进行 Dart 字符串操作

Google Maps 和 WebView Plugin 现已做好生产准备

在 Flutter 团队中,我们通常谨慎地将某些东西标记为“生产就绪”,直到我们自己对其进行彻底测试。在 google_maps_flutterwebview_flutter Plugin 的情况下,限制因素一直是底层的 Platform Views 实现,它允许来自 Android 和 iOS 的原生 UI 组件托管在 Flutter 应用中。在此版本的 Flutter 中,我们很高兴地宣布,我们已充分增强了框架管道,足以宣布这两个 Plugin 为生产就绪。

webview_flutter Plugin 托管 flutter.dev

在 Flutter 1.22 中,我们添加了一个替代的 Platform Views 实现,它修复了 Android 视图的所有已知键盘和辅助功能问题。此外,它与 Android API 级别 19 及更高版本配合使用(以前需要级别 20)。我们还在 iOS 上进行了线程改进,这些改进使平台视图更有效、更健壮(并且不再需要将 io.flutter.embedded_views_preview 标志添加到您的 iOS Info.plist 中)。

webview_flutter Plugin 支持新的 Android Platform Views 模式,但目前需要 手动启用。一旦它在更广泛的社区中得到更多使用,我们将在未来的版本中默认启用它。

Google Maps 和 WebView Plugin 已经从 Platform Views 中的改进中受益。如果您想使用 Platform Views 在 iOS 或 Android 上托管您自己的原生 UI 组件,您可以在 使用 Platform Views 在 Flutter 应用中托管原生 Android 和 iOS 视图 上了解如何操作。

如果您以前在 Flutter 应用中使用过 导航,您可能已经注意到核心数据结构(用户正在浏览的页面堆栈)对您隐藏了。相反,要管理它,您会调用 Navigator.pop() 或 Navigator.push()。例如,假设您想在主页上显示一个 Widget 列表,并允许用户点击其中一个 Widget 以进入专门针对该颜色的详细信息页。

这两个屏幕可以这样实现:

使用最简单的 Navigator 1.0 样式可以让您以看起来非常简单的方式在这两个屏幕之间导航:

调用 Navigator.push() 是将另一个页面推到第一个页面之上的所需操作,从而创建一个包含两个页面的堆栈。但是,与在 ColorListScreen 的 build 方法中创建的 Container 列表不同,该堆栈对您隐藏了。由于它被隐藏了,因此很难管理其他场景,例如处理由原生嵌入提供的初始路由的深层链接,例如来自网页的 URL 或来自 Android 的 intent。管理相同页面不同排列之间的嵌套路由也极其困难。

Navigator 2.0 通过使页面堆栈可见来解决这些问题以及更多问题。以下是在 ColorListScreen 和 ColorScreen 之间导航的更新示例:

应用明确地创建一个 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,我们认为您会喜欢它。

预览:Android 的状态恢复

此版本中可供您体验的新功能是对 Android 上的状态恢复 的支持。这是我们 最受欢迎的功能之一,获得了 217 个点赞!

对于那些不熟悉状态恢复需求的人来说,移动操作系统可能会终止后台应用以回收资源以供前台应用使用。发生这种情况时,操作系统会通知要终止的应用尽快保存任何 UI 状态,以便在用户返回到该应用时恢复它。如果实现正确,这将为用户提供无缝的体验,同时更好地利用设备资源。到目前为止,Flutter 不支持状态恢复,在没有框架支持的情况下正确地做到这一点非常困难。这就是我们很高兴能够为 Android 提供此功能的基础实现的原因。

以下是如何 恢复默认 Flutter Counter 应用的状态的简单示例

简而言之,每个 Widget 都获得一个存储桶,该存储桶使用唯一的 ID 与 RestorationMixin 关联。通过使用 RestorableProperty 类型(此处使用的是 RestorableInt)来存储 UI 特定的数据,并通过将该数据与状态恢复功能关联,数据将在 Android 终止应用之前自动存储,并在应用恢复时恢复。就这样。存储在 Restoration* 类型中的任何数据,例如 RestorableInt、RestorableString 和 RestorableTextEditingController(我们有很多这样的类型),都将被恢复。如果我们没有涵盖您希望恢复的所有类型,您可以通过扩展 RestorableProperty<T> 创建您自己的类型。

为了对状态恢复进行自动化测试,我们已向 WidgetTester 添加了一个新的 restartAndRestore API。为了手动测试,最简单的方法是在 Android 设备上启动启用了状态恢复的 Flutter 应用,在 Android 的开发者设置中启用“不保留活动”,运行 Flutter 应用,将其置于后台,然后返回到它。此时,Android 将终止并恢复您的应用,因此您可以查看一切是否按预期工作。

虽然我们很高兴将此状态恢复的预览版本交给您,但仍有更多工作要做。例如,状态恢复不仅适用于 Android,iOS 应用也可以从中受益。此外,我们正在忙于更新我们自己的 Widget,以在恢复期间保持其状态。我们已经在 Scrollable 类(例如 ListView 和 SingleChildScrollView)(记住用户的滚动位置)和 TextField(恢复用户输入的文本)中提供了支持,并计划将其扩展到其他 Widget。

但是,我们尚未添加的关键恢复支持,也是使它成为预览版本的原因是导航(1.0 或 2.0)。这意味着用户在应用中的位置将不会被恢复。该功能将很快在测试版中推出,并在 Flutter 的下一个稳定版本中推出。

预览:为无与伦比的输入和显示频率提供流畅的滚动效果

Flutter 团队与我们内部的 Google 合作伙伴合作,在输入频率和显示频率不相同的情况下大大改善了滚动的性能。例如,Pixel 4 的输入频率为 120hz,而显示频率为 90hz。这种不匹配会导致滚动时出现性能损失。使用新的 resamplingEnabled 标志,您可以利用我们在 Flutter 中完成的性能工作来解决此问题:

根据所涉及的频率差异,通过启用此标志,您可能会看到滚动时的卡顿减少高达 97%。当我们确定这是最佳体验时,我们计划在未来的版本中默认启用此标志。

一个新的统一 Dart 开发者工具

与往常一样,更新 Flutter 不仅仅意味着引擎和框架,还包括工具。Flutter 1.22 包括新的 Dart 版本(2.10),并且有一个新的 dart CLI 工具,您可能会发现它也很有用。

Dart 历史上拥有许多较小的开发者工具(例如用于格式化的 dartfmt 和用于代码分析的 dartanalyzer)。在 Dart 2.10 中新增了一个统一的 dart 开发者工具,它与 flutter 工具非常相似。

Screenshot of the output of `dart help`.

从今天的 Flutter 1.22 SDK 开始,您会发现 <flutter-sdk>/bin 文件夹(您可能将其放在 PATH 中)包含 flutter 和 dart 命令。有关更多详细信息,请参阅 Dart 2.10 部落格文章

应用大小分析工具

作为 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 代码的包级别分解。

Flutter Gallery 发布的 APK 的示例分解

此摘要对于快速识别应用程序包大小使用情况中的热点很有用。此外,收集的数据还可用作 Dart DevTools 中的 JSON 文件,它允许您进一步探索应用的内容,查明大小问题,并通过遵循 flutter.dev 上的说明 查看两个不同 JSON 文件之间的更改。加载 JSON 文件后,您将拥有一个界面,该界面将为您提供应用大小的树状图视图。

Dart DevTools 中的示例 APK 分解

有关使用应用大小工具可以执行的操作的更多详细信息,请阅读 flutter.dev 上的使用应用大小工具文档

预览:DevTools 中更新的网络页面

此版本中的另一个 DevTools 预览功能是能够在 网络 选项卡中查看 HTTP 和 HTTPS 响应正文。

若要启用此功能,请确保您通过 flutter channel devflutter channel upgrade 位于 Flutter dev 频道。

此外,对于有大量网络流量的应用,我们提供搜索和筛选功能。

有关 网络 选项卡文档,请参阅 flutter.dev 上的使用网络视图

IntelliJ 中托管的 DevTools Inspector 选项卡

一段时间以来,我们一直在维护我们 Flutter 某些工具的两个副本,例如 IntelliJ 中的 Inspector 窗格和 Dart DevTools 中的 Inspector 选项卡。这不仅会降低我们的速度,因为我们必须维护两个代码库,而且某些功能(例如布局资源管理器)尚未加入 IntelliJ Plugin。因此,为了解决这两个问题,我们启用了直接在 IntelliJ 中托管来自 Dart DevTools 的 Inspector 选项卡的功能。

请注意布局资源管理器的添加,您可以在代码旁边使用它。若要打开此选项,请转到 首选项 > 语言和框架 > Flutter > 启用嵌入式 DevTools Inspector

Visual Studio Code 中改进的输出链接

所有 Flutter 开发者都会遇到的一个常规操作是从终端或堆栈跟踪中的错误输出开始。在 Visual Studio Code 的 Flutter 扩展的最新版本中,这些链接现在将被正确地解析,以启用从输出中的链接直接进行跳转。

这看起来似乎是一个小事情,但对这一功能的初步反馈已经非常积极。

与往常一样,这里列出的工具更改太多,但我建议您查看以下公告以获取详细信息:

客户案例:EasyA

EasyA 是一款订阅应用,旨在让学龄学生通过即时消息与优秀的导师联系,并使用 Flutter 编写。最近它被 Apple 评为 Apple 的“今日应用”

“当学校今年早些时候开始上网时,我们知道我们需要快速推出我们的辅导应用来帮助学生。使用 Flutter 进行开发的超快速度意味着我们能够为 iOS 和 Android 实现获奖设计,并发布到网页——恰逢封锁期间!通常情况下,这是不可能实现的。但由于 Flutter 允许我们同时定位所有三个平台,因此我们能够高效地共享代码,并充分利用我们的小型开发者团队。”
— 菲利普·郭,[EasyA](https://easya.io/) 的联合创始人

重大更改

与往常一样,我们一直努力将重大更改的数量降至最低。以下是 Flutter 1.22 版本的列表。

总结

Flutter 1.22 稳定版本可能是在上一个版本之后快速发布的,但它包含了如此多的优秀内容,以至于这篇文章无法全部提及。我们希望此版本能帮助您为 iOS 和 Android 构建出色的应用,我们迫不及待地想看看您将会实现什么!感谢您的支持——我们为你们构建 Flutter。


宣布 Flutter 1.22 最初发布在 Flutter 上的 Medium,人们在那里通过突出显示和回应这个故事,继续进行讨论。

http://creativecommons.org/licenses/by/4.0/