跳到主内容

常见问题

关于 Flutter 的常见问题解答。

介绍

#

此页面收集了关于 Flutter 的一些常见问题。您也可以查看以下专业领域的常见问题解答

什么是 Flutter?

#

Flutter 是 Google 的便携式 UI 工具包,用于通过单一代码库构建美观、原生编译的移动、Web 和桌面应用程序。Flutter 可与现有代码配合使用,被世界各地的开发者和组织使用,并且是免费开源的。

Flutter 是为谁准备的?

#

对于用户来说,Flutter 让精美的应用焕发活力。

对于开发者来说,Flutter 降低了构建应用的门槛。它加快了应用开发速度,并降低了跨平台应用生产的成本和复杂性。

对于设计师来说,Flutter 提供了一个高端用户体验的画布。Fast Company 曾将 Flutter 描述为十年中最顶尖的设计理念之一,因为它能够将概念转化为生产代码,且无需受制于典型框架带来的折衷方案。它还充当了一个高效的原型设计工具,配有如 FlutterFlow 等拖拽式工具,以及像 Zapp! 这样的基于 Web 的 IDE。

对于工程经理和企业来说,Flutter 允许将应用开发者统一为一个单一的移动、Web 和桌面应用团队,通过单一代码库为多个平台构建品牌应用。Flutter 加速了功能开发,并同步了整个客户群的发布时间表。

使用 Flutter 需要多少开发经验?

#

熟悉面向对象概念(类、方法、变量等)和命令式编程概念(循环、条件等)的程序员都能轻松上手 Flutter。

我们看到许多编程经验极少的人也学会并使用 Flutter 进行原型设计和应用开发。

我可以用 Flutter 构建什么样的应用?

#

Flutter 旨在支持在 Android 和 iOS 上运行的移动应用,以及您希望在网页或桌面上运行的交互式应用。

需要提供高度品牌化设计的应用特别适合使用 Flutter。当然,您也可以使用 Flutter 创建与 Android 和 iOS 设计语言相匹配的像素级完美体验。

Flutter 的 包生态系统 支持各种硬件(如摄像头、GPS、网络和存储)和服务(如支付、云存储、身份验证和广告)。

谁开发了 Flutter?

#

Flutter 是一个开源项目,由 Google 以及其他公司和个人共同贡献。

谁在使用 Flutter?

#

Google 内外的开发者都使用 Flutter 构建美观的原生编译应用,涵盖 iOS 和 Android。要了解其中一些应用,请访问 展示页面 (showcase)

Flutter 的独特之处是什么?

#

Flutter 与大多数其他构建移动应用的方案不同,因为它不依赖于 Web 浏览器技术,也不依赖于每台设备自带的小部件集。相反,Flutter 使用自己的高性能渲染引擎来绘制小部件。

此外,Flutter 的不同之处在于它只有一个轻量级的 C/C++ 代码层。Flutter 的大部分系统(合成、手势、动画、框架、小部件等)都是用 Dart(一种现代、简洁、面向对象的语言)实现的,开发者可以轻松地阅读、更改、替换或删除这些代码。这赋予了开发者对系统极大的控制权,同时也显著降低了大多数系统组件的理解门槛。

我应该用 Flutter 构建我的下一个生产级应用吗?

#

Flutter 1 于 2018 年 12 月 4 日发布,Flutter 2 于 2021 年 3 月 3 日发布,Flutter 3 于 2023 年 5 月 10 日发布。截至 2023 年 5 月,已有超过一百万个应用使用 Flutter 发布到数亿台设备上。在展示页面查看一些示例应用。

Flutter 大约每季度发布一次更新,以提高稳定性和性能,并解决用户广泛关注的需求。

Flutter 提供了什么?

#

Flutter SDK 包含什么?

#

Flutter 包括:

  • 高度优化、移动优先的 2D 渲染引擎,对文本有出色的支持
  • 现代 React 风格框架
  • 丰富的实现了 Material Design 和 iOS 风格的小部件集
  • 用于单元测试和集成测试的 API
  • 用于连接系统和第三方 SDK 的互操作与插件 API
  • 用于在 Windows、Linux 和 Mac 上运行测试的无头(Headless)测试运行器
  • Flutter DevTools(也称为 Dart DevTools),用于测试、调试和分析您的应用
  • 用于创建、构建、测试和编译应用的命令行工具

Flutter 是否支持任何编辑器或 IDE?

#

我们为 VS CodeAntigravity (AI 辅助 IDE)、Android StudioIntelliJ IDEA 提供插件。有关设置详情,请参阅 编辑器配置,关于如何使用插件的技巧,请参阅 VS CodeAndroid Studio/IntelliJ 文档。

或者,您也可以在终端中使用 flutter 命令,配合支持 Dart 编辑 的众多编辑器之一。

Flutter 是否自带框架?

#

是的!Flutter 自带现代 React 风格框架。Flutter 的框架设计为分层且可自定义(且可选)。开发者可以选择仅使用框架的一部分,甚至完全替换框架的上层。

Flutter 是否自带小部件(Widgets)?

#

是的!Flutter 自带一套高质量的 Material Design 和 Cupertino (iOS 风格) 小部件、布局和主题。当然,这些小部件只是一个起点。Flutter 的设计旨在让创建自己的小部件或自定义现有小部件变得简单。

Flutter 是否支持 Material Design?

#

是的!Flutter 和 Material 团队紧密协作,全面支持 Material 设计。有关更多信息,请查看小部件目录中的 Material 2 和 Material 3 小部件。

Flutter 是否自带测试框架?

#

是的,Flutter 提供了用于编写单元测试和集成测试的 API。了解更多关于 使用 Flutter 进行测试 的内容。

我们使用自己的测试能力来测试 SDK,并且在每次提交时都会测量我们的 测试覆盖率

Flutter 是否自带调试工具?

#

是的,Flutter 自带 Flutter DevTools(也称为 Dart DevTools)。有关更多信息,请参阅 使用 Flutter 调试Flutter DevTools 文档。

Flutter 是否自带依赖注入框架?

#

我们没有提供官方的预设方案,但社区有许多提供依赖注入和服务定位的包,例如 injectableget_itkiwiriverpod

技术

#

Flutter 是用什么技术构建的?

#

Flutter 是使用 C、C++、Dart、Skia(2D 渲染引擎)和 Impeller(iOS 上的默认渲染引擎)构建的。查看此 架构图 以更清楚地了解主要组件。有关 Flutter 分层架构的详细描述,请阅读 架构概览

Flutter 如何在 Android 上运行我的代码?

#

引擎的 C 和 C++ 代码使用 Android 的 NDK 编译。Dart 代码(SDK 的代码以及您的代码)被提前(AOT)编译为原生的 ARM 和 x86-64 库。这些库被包含在一个“运行器”Android 项目中,整个项目被构建成一个 .apk。应用启动时,会加载 Flutter 库。任何渲染、输入、事件处理等都委托给编译后的 Flutter 和应用代码。这与许多游戏引擎的工作方式类似。

在调试模式下,Flutter 使用虚拟机 (VM) 来运行其代码,以实现有状态的热重载功能。该功能允许您在不重新编译的情况下对正在运行的代码进行更改。在此模式下运行时,应用右上角会出现一个“debug”横幅,提醒您性能并非成品发布应用的最终特性。

Flutter 如何在 iOS 上运行我的代码?

#

引擎的 C 和 C++ 代码使用 LLVM 编译。Dart 代码(SDK 的代码以及您的代码)被提前(AOT)编译为原生的 ARM 库。该库被包含在一个“运行器”iOS 项目中,整个项目被构建成一个 .ipa。应用启动时,会加载 Flutter 库。任何渲染、输入、事件处理等都委托给编译后的 Flutter 和应用代码。这与许多游戏引擎的工作方式类似。

在调试模式下,Flutter 使用虚拟机 (VM) 来运行其代码,以实现有状态的热重载功能。该功能允许您在不重新编译的情况下对正在运行的代码进行更改。在此模式下运行时,应用右上角会出现一个“debug”横幅,提醒您性能并非成品发布应用的最终特性。

Flutter 是否使用我操作系统内置的平台小部件?

#

不是。相反,Flutter 提供了一套由其框架和引擎管理并渲染的小部件(包括 Material Design 和 Cupertino (iOS 风格) 小部件)。您可以浏览 Flutter 小部件目录

我们相信最终结果是更高质量的应用。如果我们重用内置的平台小部件,Flutter 应用的质量和性能将受限于这些小部件的灵活性和质量。

例如,在 Android 中,有一套硬编码的手势规则用于消除冲突。在 Flutter 中,您可以编写自己的手势识别器,它是手势系统中的一等公民。此外,由不同人编写的两个小部件可以协同工作来消除手势歧义。

现代应用设计趋势指向设计师和用户需要更具动感、以品牌为主导的 UI。为了实现这种定制化、美观的设计水平,Flutter 的架构设计为直接驱动像素,而不是使用内置小部件。

通过使用相同的渲染器、框架和一组小部件,从同一代码库发布到多个平台变得更容易,无需为了对齐不同的功能集和 API 特性而进行谨慎且昂贵的规划。

通过为您的所有代码使用单一语言、单一框架和单一库(无论您的 UI 是否针对每个平台有所不同),我们也旨在帮助降低应用开发和维护成本。

当我的移动操作系统更新并引入新小部件时会发生什么?

#

Flutter 团队密切关注 iOS 和 Android 对新移动小部件的采用和需求,并致力于与社区合作,为新小部件构建支持。这项工作可能以底层框架功能、新的可组合小部件或新的小部件实现的形式出现。

Flutter 的分层架构旨在支持众多的组件库,我们鼓励并支持社区构建和维护组件库。

当我的移动操作系统更新并引入新的平台功能时会发生什么?

#

Flutter 的互操作和插件系统旨在允许开发者立即访问新的移动操作系统特性和能力。开发者无需等待 Flutter 团队来公开这些新的移动操作系统功能。

Flutter 支持热更新(Code Push)吗?

#

热更新(Code Push),即直接向用户设备推送应用更新的能力,并不直接由 Flutter 支持。不过,我们了解到有一个第三方解决方案,名为 Shorebird。请注意,这并非官方认可或推荐。

我可以使用哪些操作系统来构建 Flutter 应用?

#

Flutter 支持在 Linux、macOS、ChromeOS 和 Windows 上进行开发。

Flutter 是用什么语言编写的?

#

Dart,一种快速增长的现代语言,针对客户端应用进行了优化。底层的图形框架和 Dart 虚拟机是用 C/C++ 实现的。

为什么 Flutter 选择使用 Dart?

#

在初始开发阶段,Flutter 团队考察了许多语言和运行时,最终为框架和小部件采用了 Dart。Flutter 使用四个主要维度进行评估,并考虑了框架作者、开发者和最终用户的需求。我们发现许多语言满足部分要求,但 Dart 在我们所有的评估维度上都得分很高,并满足了我们所有的需求和标准。

Dart 运行时和编译器支持 Flutter 所需的两个关键特性组合:基于 JIT 的快速开发周期(允许在具备类型的语言中进行形状更改和有状态热重载),以及能够生成高效 ARM 代码的 Ahead-of-Time (AOT) 编译器,确保生产部署的快速启动和可预测的性能。

此外,我们有机会与 Dart 社区紧密合作,该社区正积极投入资源以改善 Dart 在 Flutter 中的使用体验。例如,当我们采用 Dart 时,该语言还没有用于生产原生二进制文件的 AOT 工具链,这对于实现可预测的高性能至关重要;但现在该语言具备了这一功能,因为 Dart 团队专门为 Flutter 构建了它。同样,Dart VM 以前针对吞吐量进行了优化,但该团队现在正在针对延迟优化 VM,这对 Flutter 的负载更为重要。

Dart 在以下主要标准上为我们赢得了高分:

开发者生产力

Flutter 的主要价值主张之一是,它通过允许开发者使用同一代码库为 iOS 和 Android 创建应用,从而节省了工程资源。使用一种高生产力的语言可以进一步加速开发者的进度,使 Flutter 更有吸引力。这对我们的框架团队和开发者都非常重要。Flutter 的大部分内容是用我们提供给用户的同一种语言构建的,因此我们需要在数万行代码规模下保持高效,同时不牺牲框架和小部件对开发者的易用性和可读性。

面向对象

对于 Flutter,我们想要一种适合 Flutter 问题领域的语言:创建可视化用户体验。该行业在用面向对象语言构建 UI 框架方面拥有数十年的经验。虽然我们可以使用非面向对象语言,但这将意味着为了解决几个困难问题而重新发明轮子。此外,绝大多数开发者都拥有面向对象开发的经验,这使得学习如何使用 Flutter 进行开发变得更容易。

可预测的高性能

使用 Flutter,我们希望赋能开发者创建快速、流畅的用户体验。为了实现这一目标,我们需要能够在每个动画帧期间运行大量的端开发者代码。这意味着我们需要一种既能提供高性能又能提供可预测性能的语言,且不会出现导致掉帧的周期性停顿。

快速内存分配

Flutter 框架使用一种函数式风格的流程,非常依赖于底层内存分配器高效处理小型、短命的分配。这种风格是在具有此属性的语言中开发的,在缺乏此功能的语言中无法高效工作。

Flutter 可以运行任何 Dart 代码吗?

#

Flutter 可以运行不直接或间接导入 dart:mirrorsdart:html 的 Dart 代码。

Flutter 可以将 Dart 编译为 JavaScript 吗?

#

Flutter 使用 js.dart 包将 Dart 编译为 JavaScript。

Flutter 引擎有多大?

#

2021 年 3 月,我们测量了一个 最小 Flutter 应用(无 Material Components,仅一个 Center 小部件,使用 flutter build apk --split-per-abi 构建)的下载大小,作为发布 APK 捆绑并压缩后,ARM32 约为 4.3 MB,ARM64 约为 4.8 MB。

在 ARM32 上,核心引擎约为 3.4 MB(压缩后),框架 + 应用代码约为 765 KB(压缩后),LICENSE 文件为 58 KB(压缩后),必要的 Java 代码 (classes.dex) 为 120 KB(压缩后)。

在 ARM64 上,核心引擎约为 4.0 MB(压缩后),框架 + 应用代码约为 659 KB(压缩后),LICENSE 文件为 58 KB(压缩后),必要的 Java 代码 (classes.dex) 为 120 KB(压缩后)。

这些数字是使用 apkanalyzer 测量的,该工具也内置于 Android Studio 中

在 iOS 上,同一个应用的发布 IPA 在 iPhone X 上的下载大小为 10.9 MB(根据 Apple 的 App Store Connect 报告)。IPA 比 APK 大主要是因为 Apple 会对 IPA 内的二进制文件进行加密,导致压缩效率降低(请参阅 Apple QA1795 文档中 iOS 应用商店具体注意事项 部分)。

当然,我们建议您测量自己的应用。为此,请参阅 测量您的应用大小

Flutter 如何定义像素?

#

Flutter 使用逻辑像素,通常仅简称为“像素”。Flutter 的 devicePixelRatio 表示物理像素与逻辑 CSS 像素之间的比例。

功能

#

我可以期待什么样的应用性能?

#

通常情况下,您可以期待出色的性能。Flutter 旨在帮助开发者轻松实现恒定的 60fps。Flutter 应用使用原生编译代码运行,因此不涉及解释器。这意味着 Flutter 应用启动很快。

Flutter 在使用原生代码时的性能取决于您的 应用架构。为了获得最佳性能,请熟悉 Flutter 的 平台通道 (platform channels)。这些通道提供了一种用于与原生代码通信的异步消息传递系统。

要了解更多关于性能和 Flutter 的信息,请参阅 性能常见问题解答

我可以期待什么样的开发周期?从编辑到刷新需要多长时间?

#

Flutter 实现了热重载 (hot reload) 开发周期。您可以在设备或模拟器上获得亚秒级的重载时间。

Flutter 的热重载是有状态的 (stateful),因此应用状态在重载后会保留。这意味着您可以在嵌套深处的屏幕上快速迭代,而无需在每次重载后从主屏幕重新开始。

热重载 (hot reload)热重启 (hot restart) 有什么区别?

#

热重载通过将更新的源代码文件注入到正在运行的 Dart 虚拟机(VM)中来工作。这不仅会添加新类,还会向现有类添加方法和字段,并更改现有函数。热重启会将状态重置为应用的初始状态。

有关更多信息,请参阅 热重载

我可以将 Flutter 应用部署到哪里?

#

您可以将 Flutter 应用编译并部署到 iOS、Android、Web桌面

Flutter 在哪些设备和操作系统版本上运行?

#
  • 我们支持并测试在各种低端到高端平台上运行 Flutter。有关我们测试的平台详细列表,请参阅 受支持平台列表

  • Flutter 支持为 x86-64armeabi-v7aarm64-v8a 构建提前(AOT)编译的库。

  • 为 ARMv7 或 ARM64 构建的应用可以在许多 x86-64 Android 设备上正常运行(使用 ARM 模拟)。

  • 我们支持在多种平台上开发 Flutter 应用。请参阅每个 开发操作系统 下列出的系统要求。

Flutter 可以在 Web 上运行吗?

#

是的,Web 支持在稳定版通道中可用。有关更多详情,请查看 Web 构建说明

我可以使用 Flutter 构建桌面应用吗?

#

是的,桌面支持在 Windows、macOS 和 Linux 上处于稳定状态。

我可以在现有的原生应用中使用 Flutter 吗?

#

是的,在网站的 add-to-app 部分了解更多信息。

我可以访问传感器和本地存储等平台服务和 API 吗?

#

是的。Flutter 为开发者提供了开箱即用的对某些特定于平台的操作系统服务和 API 的访问权限。但是,我们希望避免大多数跨平台 API 中存在的“最小公分母”问题,因此我们不打算为所有原生服务和 API 构建跨平台 API。

许多平台服务和 API 在 pub.dev 上都有 现成的包。使用现有的包 非常简单

最后,我们鼓励开发者使用 Flutter 的异步消息传递系统来创建您自己与 平台和第三方 API 的集成。开发者可以根据需要公开尽可能多或尽可能少的平台 API,并构建最适合其项目的抽象层。

我可以扩展和自定义捆绑的小部件吗?

#

绝对可以。Flutter 的小部件系统设计为易于自定义。

与其让每个小部件提供大量参数,Flutter 拥抱组合。小部件由更小的小部件组成,您可以重复使用并将它们以新颖的方式组合起来制作自定义小部件。例如,与其继承通用按钮小部件,ElevatedButton 将一个 Material 小部件与一个 GestureDetector 小部件组合在一起。Material 小部件提供视觉设计,而 GestureDetector 小部件提供交互设计。

要创建具有自定义视觉设计的按钮,您可以将实现您视觉设计的小部件与 GestureDetector 组合,后者提供交互设计。例如,CupertinoButton 遵循此方法,将 GestureDetector 与实现其视觉设计的其他几个小部件组合在一起。

组合让您对小部件的视觉和交互设计拥有最大控制权,同时也允许大量代码复用。在框架中,我们将复杂的小部件分解为分别实现视觉、交互和运动设计的部分。您可以随心所欲地重新混合这些小部件,制作出拥有完整表达能力的自定义小部件。

为什么要跨 iOS 和 Android 共享布局代码?

#

您可以选择为 iOS 和 Android 实现不同的应用布局。开发者可以自由地在运行时检查移动操作系统并渲染不同的布局,尽管我们发现这种做法很少见。

越来越多地,我们看到移动应用布局和设计演变为以品牌驱动,并在各平台之间统一。这意味着跨 iOS 和 Android 共享布局和 UI 代码的动力非常强劲。

品牌标识和应用美学设计的自定义现在变得比严格遵守传统平台美学更为重要。例如,应用设计通常需要自定义字体、颜色、形状、动态效果等,以清晰地传达其品牌标识。

我们也看到常见的布局模式在 iOS 和 Android 之间部署。例如,“底部导航栏”模式现在可以自然地在 iOS 和 Android 上找到。移动平台之间的设计理念似乎正在融合。

我可以与移动平台的默认编程语言进行交互吗?

#

是的,Flutter 支持调用平台代码,包括在 Android 上集成 Java 或 Kotlin 代码,以及在 iOS 上集成 Swift 或 Objective-C 代码。这是通过灵活的消息传递风格启用的,其中 Flutter 应用可以使用 BasicMessageChannel 向移动平台发送和接收消息。

通过 平台通道 了解更多关于在 Flutter 中访问平台和第三方服务的信息。

这是一个 示例项目,展示了如何使用平台通道访问 iOS 和 Android 上的电池状态信息。

Flutter 是否自带反射/镜像(reflection / mirrors)系统?

#

不是。Dart 包含 dart:mirrors,它提供类型反射。但由于 Flutter 应用是为生产环境预编译的,且二进制大小在移动应用中始终是一个考量,因此该库在 Flutter 应用中不可用。

使用静态分析,我们可以剔除任何未使用的内容(“树摇/tree shaking”)。如果您导入了一个巨大的 Dart 库,但只使用了其中一个自包含的两行方法,那么您只需为那两行方法付出代价,即使该 Dart 库本身导入了数十个其他库。只有在 Dart 可以在编译时识别代码路径的情况下,这种保证才是安全的。迄今为止,我们已经为特定需求找到了提供更好权衡的方法,例如代码生成。

是否支持国际化和本地化?

#

是的,Flutter 支持国际化 (i18n) 和本地化 (l10n),以便您的应用可以适应不同的语言和文化。您可以在 国际化文档 中了解更多信息。

支持哪些辅助功能?

#

Flutter 支持严格的辅助功能要求 (a11y)。例如,支持屏幕阅读器、大文本、色彩对比度和硬件开关控制。要了解更多信息,请参阅 辅助功能文档

我该如何为 Flutter 编写并行或并发应用?

#

Flutter 支持 Isolate。Isolate 是 Flutter 虚拟机中的独立堆,它们能够并行运行(通常实现为独立的线程)。Isolate 通过发送和接收异步消息进行通信。

查看一个 在 Flutter 中使用 Isolate 的示例

我可以在 Flutter 应用的后台运行 Dart 代码吗?

#

是的,您可以在 iOS 和 Android 上在后台进程中运行 Dart 代码。有关更多信息,请参阅免费的中篇博客文章 使用 Flutter 插件和地理围栏在后台执行 Dart 代码

我可以在 Flutter 中使用 JSON/XML/Protobufs 等吗?

#

绝对可以。在 pub.dev 上有用于 JSON、XML、Protobufs 以及许多其他实用程序和格式的库。

有关在 Flutter 中使用 JSON 的详细说明,请查看 JSON 教程

我可以使用 Flutter 构建 3D (OpenGL) 应用吗?

#

今天我们不支持使用 OpenGL ES 或类似技术进行 3D 渲染。我们有长期计划来公开优化的 3D API,但目前我们专注于 2D。

为什么我的 APK 或 IPA 这么大?

#

通常,包括图像、声音文件、字体等在内的资产是 APK 或 IPA 的大部分。Android 和 iOS 生态系统中的各种工具可以帮助您了解 APK 或 IPA 内部的内容。

此外,请确保使用 Flutter 工具为您的 APK 或 IPA 创建发布构建 (release build)。发布构建通常比调试构建 (debug build) 小得多

了解更多关于创建 Android 应用的发布构建 以及创建 iOS 应用的发布构建 的信息。此外,请查看 测量您的应用大小

Flutter 应用可以在 Chromebook 上运行吗?

#

我们已经看到 Flutter 应用在某些 Chromebook 上运行。我们正在追踪 与在 Chromebook 上运行 Flutter 相关的问题

Flutter 是否具备 ABI 兼容性?

#

Flutter 和 Dart 不提供应用二进制接口 (ABI) 兼容性。提供 ABI 兼容性不是 Flutter 或 Dart 当前的目标。

Flutter 如何处理滚动?

#

每个应用平台都使用自定义的滚动实现,以便滚动效果与该平台的原生滚动外观和感觉相匹配。要了解更多关于使用 Flutter 滚动的信息,请参阅 滚动 文档。

框架

#

为什么 build() 方法是在 State 类中,而不是在 StatefulWidget 中?

#

Widget build(BuildContext context) 方法放在 State 中,而不是将 Widget build(BuildContext context, State state) 方法放在 StatefulWidget 中,为开发者在继承 StatefulWidget 时提供了更大的灵活性。您可以阅读更 关于 State.build API 文档的详细讨论

Flutter 的标记语言在哪里?为什么 Flutter 没有标记语法?

#

Flutter UI 是用命令式、面向对象的语言(Dart,与构建 Flutter 框架的语言相同)构建的。Flutter 不自带声明式标记语言。

我们发现动态构建的 UI 代码提供了更大的灵活性。例如,我们发现僵化的标记系统很难表达和生成具有定制行为的小部件。

我们还发现,我们的“代码优先”方法能更好地支持热重载和动态环境适配等特性。

可以创建一个自定义语言,然后在运行时将其转换为小部件。因为构建方法“只是代码”,它们可以做任何事情,包括解释标记并将其转化为小部件。

我的应用右上角有一个调试横幅。为什么会看到这个?

#

默认情况下,flutter run 命令使用调试构建配置。

调试配置在虚拟机(VM)中运行您的 Dart 代码,实现具有 热重载 的快速开发周期(发布构建使用标准的 AndroidiOS 工具链进行编译)。

调试配置还会检查所有断言,这有助于您在开发初期及早发现错误,但这会带来运行时的开销。“Debug”横幅表示启用了这些检查。您可以使用 flutter run--profile--release 标志来运行不带这些检查的应用。

如果您的 IDE 使用了 Flutter 插件,您可以在 Profile 或 Release 模式下启动应用。对于 VS Code,使用 运行 > 开始调试运行 > 以非调试模式运行 菜单条目。对于 IntelliJ,使用 运行 > 以 Profile 模式运行 Flutter发布模式 菜单条目。

Flutter 框架使用什么编程范式?

#

Flutter 是一个多范式编程环境。过去几十年来开发的许多编程技术在 Flutter 中都有使用。我们根据每种技术的优势,将其运用在最适合的场景中。以下顺序不分先后:

组合 (Composition)

Flutter 使用的主要范式是使用行为范围狭窄的小对象,组合在一起以获得更复杂的效果,有时称为积极组合 (aggressive composition)。Flutter 小部件库中的大多数小部件都是以这种方式构建的。例如,Material TextButton 类是使用一个 IconTheme、一个 InkWell、一个 Padding、一个 Center、一个 Material、一个 AnimatedDefaultTextStyle 和一个 ConstrainedBox 构建的。InkWell 是使用 GestureDetector 构建的。Material 是使用 AnimatedDefaultTextStyle、一个 NotificationListener 和一个 AnimatedPhysicalModel 构建的。依此类推,底层全是小部件。

函数式编程

整个应用可以仅使用 StatelessWidget 构建,它们本质上是描述参数如何映射到其他函数的函数,最终归结为计算布局或绘制图形的原语。(此类应用无法轻松拥有状态,因此通常是非交互式的。)例如,Icon 小部件本质上是一个函数,它将其参数(coloriconsize)映射为布局原语。此外,大量使用了不可变数据结构,包括整个 Widget 类层次结构以及众多辅助类,如 RectTextStyle。在更小的范围内,Dart 的 Iterable API(大量使用了函数式风格,如 map、reduce、where 等)经常被用于处理框架中的值列表。

事件驱动编程

用户交互由分发给已注册事件处理程序回调的事件对象表示。屏幕更新通过类似的回调机制触发。用作动画系统基础的 Listenable 类,将具有多个监听器的事件订阅模型形式化了。

基于类的面向对象编程

框架的大多数 API 都是使用具有继承关系的类构建的。我们采用一种在基类中定义非常高级的 API,然后在其子类中迭代地进行专门化的方法。例如,我们的渲染对象有一个基类(RenderObject),它对坐标系无感知,然后我们有一个子类(RenderBox),它引入了几何图形应基于笛卡尔坐标系(x/宽度 和 y/高度)的观点。

基于原型的面向对象编程

ScrollPhysics 类链接实例以在运行时动态组合适用于滚动的物理效果。这让系统能够例如将分页物理与特定于平台的物理效果组合,而无需在编译时选择平台。

命令式编程

直接的命令式编程(通常与封装在对象中的状态结合使用)用于提供最直观的解决方案的地方。例如,测试是以命令式风格编写的,首先描述被测场景,然后列出测试必须满足的不变量,然后根据测试需要推进时钟或插入事件。

响应式编程

小部件树和元素树有时被称为响应式,因为小部件构造函数中提供的新输入会立即通过小部件的 build 方法传播为对底层小部件的更改,而底层小部件中的更改(例如,响应用户输入)会通过事件处理程序传播回树中。框架中存在函数响应式和命令响应式两方面的特性,具体取决于小部件的需求。build 方法仅包含描述小部件如何响应其配置更改的表达式的小部件是函数式响应式小部件(例如,Material Divider 类)。build 方法在多个语句上构造子项列表,描述小部件如何响应其配置更改的小部件是命令式响应式小部件(例如,Chip 类)。

声明式编程

小部件的 build 方法通常是一个具有多层嵌套构造函数的单一表达式,使用 Dart 的严格声明式子集编写。此类嵌套表达式可以机械地转换为任何具有足够表达能力的标记语言,或从其中转换。例如,UserAccountsDrawerHeader 小部件有一个很长的 build 方法(20 多行),由一个单一的嵌套表达式组成。这也可以与命令式风格相结合,以构建在纯声明式方法中难以描述的 UI。

泛型编程

类型可以用来帮助开发者及早发现编程错误。Flutter 框架利用泛型编程在这方面提供帮助。例如,State 类根据其关联小部件的类型进行了参数化,以便 Dart 分析器可以捕获状态和小部件的不匹配。同样,GlobalKey 类带有一个类型参数,以便它可以以类型安全的方式(使用运行时检查)访问远程小部件的状态;Route 接口使用预期在 弹出 (pop) 时使用的类型进行参数化;诸如 ListMapSet 等集合都进行了参数化,以便在分析期间或调试时的运行时可以及早发现不匹配的元素。

并发编程

Flutter 大量使用 Future 和其他异步 API。例如,动画系统通过完成一个 future 来报告动画何时完成。图像加载系统类似地使用 future 来报告加载何时完成。

约束编程

Flutter 中的布局系统使用一种弱形式的约束编程来确定场景的几何形状。约束(例如,对于笛卡尔框,最小和最大宽度以及最小和最大高度)从父级传递给子级,子级选择一个满足这些约束的结果几何形状(例如,对于笛卡尔框,一个大小,具体为宽度和高度)。通过使用这种技术,Flutter 通常可以用一次通过来布置整个场景。

项目

#

我可以在哪里获得支持?

#

如果您认为遇到了错误,请在我们的 问题追踪器 (issue tracker) 中提交。对于“如何操作”类型的问题,您也可以使用 Stack Overflow。对于讨论,请加入我们的邮件列表 flutter-dev@googlegroups.com 或在 Discord 上寻找我们。

有关更多信息,请参阅我们的 社区 页面。

我该如何参与?

#

Flutter 是开源的,我们鼓励您做出贡献。您可以从在我们的 问题追踪器 中提交功能请求和 Bug 开始。

我们建议您加入我们的邮件列表 flutter-dev@googlegroups.com,让我们知道您是如何使用 Flutter 的以及您想用它做什么。

如果您有兴趣贡献代码,可以先阅读我们的 贡献指南,并查看我们的 简单入门问题列表

最后,您可以与乐于助人的 Flutter 社区建立联系。有关更多信息,请参阅 社区 页面。

您还可以与其他开发者在 Flutter Discord 上交流。

Flutter 是开源的吗?

#

是的,Flutter 是一项开源技术。您可以在 GitHub 上找到该项目。

哪些软件许可证适用于 Flutter 及其依赖项?

#

Flutter 包括两个组件:一个作为动态链接二进制文件发布的引擎,以及一个引擎加载的独立二进制文件 Dart 框架。该引擎使用具有许多依赖项的多个软件组件;请在其 许可文件 中查看完整列表。

框架是完全自包含的,并且 仅需要一个许可证

此外,您使用的任何 Dart 包可能都有自己的许可要求。

我该如何确定我的 Flutter 应用需要展示哪些许可证?

#

有一个 API 可以查找您需要展示的许可证列表:

谁在开发 Flutter?

#

我们都在做!Flutter 是一个开源项目。目前,大部分开发工作由 Google 的工程师完成。如果您对 Flutter 感到兴奋,我们鼓励您加入社区并 为 Flutter 做出贡献

Flutter 的指导原则是什么?

#

我们相信以下几点:

  • 为了触达每一位潜在用户,开发者需要针对多个移动平台。
  • 现有的 HTML 和 WebView 由于自动行为(滚动、布局)和旧版支持,使得始终保持高帧率并提供高保真体验变得具有挑战性。
  • 今天,多次构建同一个应用的成本太高:它需要不同的团队、不同的代码库、不同的工作流程、不同的工具等。
  • 开发者想要一种更简单、更好的方法来使用单一代码库构建多个目标平台的移动应用,且不希望牺牲质量、控制权或性能。

我们专注于三件事:

控制权 (Control)

开发者应获得对系统所有层的访问权限和控制权。这导致:

性能

用户应获得完美流畅、响应迅速、无卡顿的应用。这导致:

保真度 (Fidelity):

每个人都应获得精确、美观、愉悦的应用体验。

苹果会拒绝我的 Flutter 应用吗?

#

我们不能代表 Apple,但他们的 App Store 包含许多使用 Flutter 等框架技术构建的应用。事实上,Flutter 使用与 Unity 相同的基本架构模型,Unity 是为 Apple Store 上许多最流行游戏提供驱动的引擎。

Apple 经常推荐使用 Flutter 构建的精心设计的应用,包括 HamiltonReflectly

与提交到 Apple Store 的任何应用一样,使用 Flutter 构建的应用应遵循 Apple 的 应用商店提交指南