Flutter 简介
Flutter是Google开源的构建用户界面(UI)工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台。 Flutter 开源、免费,拥有宽松的开源协议,适合商业项目。
- 发展历程及版本升级
- 2015年5月3日上线。
- 2018年12月5日正式发布1.0Release版本。
- 2021年3月4日推出2.0Release版本。
- 2022年2月4日推出2.10Release版本。
- 升级2.0
-
自 Flutter 1.0 发布至今已有两年多的时间,在如此短暂的时间内,我们解决了 24,541 个 issue,合并了来自 765 个贡献者的 17,039 个 PR。自九月发布 Flutter 1.22 以来,我们已解决 5,807 个 issue,合并了来自 298 个贡献者的 4,091 个 PR。在此特别感谢广大的贡献者,将业余时间慷慨地投入到 Flutter 项目的优化中。Flutter 2 的杰出贡献者有 xu-baolin (贡献了 46 个 PR)、a14n (贡献了 32 个 PR;专注于为 Flutter 引入空安全) 和 hamdikahloun (贡献了 20 个 PR;优化了一系列 Flutter 插件)。然而,为 Flutter 项目做出贡献的不只有开发者,还有我们负责评审 1,525 个 PR 的众多 PR 评审员,其中包括 hamdikahloun (身兼数职!)、CareF 和 YazeedAlKhalaf (年仅 16 岁!) 等人。
-
Flutter web 的支持已经从 Beta 版过渡到稳定阶段 -
健全的空安全(null safety)是对 Dart 语言的重要补充 -
Flutter 对桌面设备的支持已经进入稳定版本的前期准备阶段
-
Flutter 已可在三个平台 (Android、iOS 和 web) 上为生产环境的应用提供支持,还有三个平台仍处于测试阶段 (Windows、macOS 和 Linux)
-
Google Mobile Ads 发布 Beta 版
-
新版本提供了 178 个与 iOS 相关的合并 PR,其中包括将状态恢复 (State Restoration) 引入 iOS 的 23495,应开发者需求——不用打开 Xcode 就可以直接从命令行建立 IPA 的 67781,以及更新 CocoaPods 版本以配合最新工具的 69809。此外,我们还在 Cupertino 设计语言实现中添加了一些 iOS 小部件
-
新版 Flutter 新增了两个 Widget,分别是 AutocompleteCore 和 ScaffoldMessenger
-
混合编程 (Add-to-App),您可以通过这种方法,在保留现有原生代码库的同时,在两个移动平台间重复使用 Flutter 代码
-
Flutter Fix,可借此找到已弃用 API 的相同列表,完成快速修复
-
Flutter DevTools
-
DartPad 现已更新并支持 Flutter 2
-
生态系统更新
- Core
- Authentication
- Cloud Firestore
- Cloud Functions
- Cloud Messaging
- Cloud Storage
- Crashlytics
-
重大变更
- 61366 继续对 clipBehavior 进行重大变更
- 66700 将默认 FittedBox 的 clipBehavior 更改为无
- 68905 从 Cupertino 颜色 API 中移除 nullOk 参数
- 69808 从 Scaffold.of 和 ScaffoldMessenger.of 中移除 nullOk 参数,为两者创建 maybeOf
- 68910 从 Router.of 中移除 nullOk 参数,使其返回非空值
- 68911 在 Localizations 中加入 maybeLocaleOf 方法
- 68736 从Media.queryOf 中移除 nullOK 参数
- 68917 从 Focus.of, FocusTraversalOrder.of 和 FocusTraversalGroup.of 中移除 nullOK
- 68921 从 Shortcuts.of, Actions.find, and Actions.handler 中移除 nullOK
- 68925 从 AnimatedList.of 和 SliverAnimatedList.of 中移除 nullOK
- 69620 从 BuildContext 中删除已弃用的方法
- 72017 删除已弃用的 CupertinoTextThemeData.brightness
- 72395 删除已弃用的 [PointerEnterEvent, PointerExitEvent].fromHoverEvent
- 72532 删除已弃用的 showDialog.child
- 72890 删除已弃用的 Scaffold.resizeToAvoidBottomPadding
- 72893 删除已弃用的 WidgetsBinding.[deferFirstFrameReport, allowFirstFrameReport]
- 72901 删除已弃用的 StatefulElement.inheritFromElement
- 72903 删除已弃用的元素方法
- 73604 删除已弃用的 CupertinoDialog
- 73745 从 Cupertino[Sliver]NavigationBar 中删除已弃用的 actionsForegroundColor
- 73746 删除已弃用的 ButtonTheme.bar
- 73747 删除 Span 弃用项
- 73748 删除已弃用的 RenderView.scheduleInitialFrame
- 73749 删除已弃用的 Layer.findAll
- 75657 在 Localizations.localeOf 移除残留的 nullOK 参数
- 74680 从 Actions.invoke 移除 nullOK 参数,并添加 Actions.maybeInvoke 方法
-
-
- 2.10 ,Flutter 团队关闭了 1843 个 Issue,合并了来⾃全球 155 位贡献者的 1525 个 PR
- Flutter 2.10 版本带来了稳定的 Windows ⽀持,无需再通过
--enable-windows-desktop标记来单独配置 Windows 桌面版应用程序的支持,因为它现在已经默认被启用 - 引擎的性能改进
- iOS 上新的增强功能——更流畅的键盘动画,它会⾃动应用在你的应用中
- Flutter 默认⽀持最新版本的 Android,即 Android 12(API 级别 31)。
- Web 平台性能优化,构建了一个新的「⾮绘制的平台视图」
- Material 3 过渡的开始,其中包括 从单一种⼦颜⾊⽣成整个配⾊⽅案 的能力
- 破坏性改动
框架优势
-
跨平台自绘引擎
- Flutter 与用于构建移动应用程序的其它大多数框架不同,因为 Flutter 既不使用 WebView,也不使用操作系统的原生控件。 相反,Flutter 使用自己的高性能渲染引擎来绘制 Widget(组件)。这样不仅可以保证在 Android 和iOS 上 UI 的一致性,也可以避免对原生控件依赖而带来的限制及高昂的维护成本。
- Flutter 底层使用 Skia 作为其 2D 渲染引擎,Skia 是 Google的一个 2D 图形处理函数库,包含字型、坐标转换,以及点阵图,它们都有高效能且简洁的表现。Skia 是跨平台的,并提供了非常友好的 API,目前 Google Chrome浏览器和 Android 均采用 Skia 作为其 2D 绘图引擎。
- 目前 Flutter 已经支持 iOS、Android、Web、Windows、macOS、Linux、Fuchsia(Google新的自研操作系统)等众多平台,但本书的示例和介绍主要是基于 iOS 和 Android 平台的,其它平台读者可以自行了解。
-
高性能
- Flutter APP 采用 Dart 语言开发。Dart 在 JIT(即时编译)模式下,执行速度与 JavaScript 基本持平。但是 Dart 支持 AOT,当以 AOT模式运行时,JavaScript 便远远追不上了。执行速度的提升对高帧率下的视图数据计算很有帮助。
- Flutter 使用自己的渲染引擎来绘制 UI ,布局数据等由 Dart 语言直接控制,所以在布局过程中不需要像 RN 那样要在 JavaScript 和 Native 之间通信,这在一些滑动和拖动的场景下具有明显优势,因为在滑动和拖动过程往往都会引起布局发生变化,所以 JavaScript 需要和 Native 之间不停的同步布局信息,这和在浏览器中JavaScript 频繁操作 DOM 所带来的问题是类似的,都会导致比较可观的性能开销。
-
采用Dart语言开发
-
这个是一个很有意思但也很有争议的问题,在了解 Flutter 为什么选择了 Dart 而不是 JavaScript 之前我们先来介绍一下之前提到过的两个概念:JIT 和 AOT。
-
程序主要有两种运行方式:静态编译与动态解释。静态编译的程序在执行前程序会被提前编译为机器码(或中间字节码),通常将这种类型称为AOT (Ahead of time)即 “提前编译”。而解释执行则是在运行时将源码实时翻译为机器码来执行,通常将这种类型称为JIT(Just-in-time)即“即时编译”。
-
AOT 程序的典型代表是用 C/C++ 开发的应用,它们必须在执行前编译成机器码;而JIT的代表则非常多,如JavaScript、python等,事实上,所有脚本语言都支持 JIT 模式。但需要注意的是 JIT 和 AOT 指的是程序运行方式,和编程语言并非强关联的,有些语言既可以以 JIT 方式运行也可以以 AOT 方式运行,如Python,它可以在第一次执行时编译成中间字节码,然后在之后执行时再将字节码实施转为机器码执行。也许有人会说,中间字节码并非机器码,在程序执行时仍然需要动态将字节码转为机器码,这不应该是 JIT 吗 ? 是这样,但通常我们区分是否为AOT 的标准就是看代码在执行之前是否需要编译,只要需要编译,无论其编译产物是字节码还是机器码,都属于AOT。在此,读者不必纠结于概念,概念就是为了传达精神而发明的,只要读者能够理解其原理即可,得其神忘其形。
-
现在我们看看 Flutter 为什么选择 Dart 语言?笔者根据官方解释以及自己对 Flutter 的理解总结了以下几条(由于其它跨平台框架都将 JavaScript 作为其开发语言,所以主要将 Dart 和 JavaScript 做一个对比):
-
开发效率高。
-
Dart 运行时和编译器支持 Flutter 的两个关键特性的组合:
-
基于 JIT 的快速开发周期:Flutter 在开发阶段采用,采用 JIT 模式,这样就避免了每次改动都要进行编译,极大的节省了开发时间;
-
基于 AOT 的发布包: Flutter 在发布时可以通过 AOT 生成高效的机器码以保证应用性能。而 JavaScript 则不具有这个能力。
-
-
高性能。
- Flutter 旨在提供流畅、高保真的的 UI 体验。为了实现这一点,Flutter 中需要能够在每个动画帧中运行大量的代码。这意味着需要一种既能提供高性能的语言,而不会出现会丢帧的周期性暂停,而 Dart 支持 AOT,在这一点上可以做的比 JavaScript 更好。
-
快速内存分配。
- Flutter 框架使用函数式流,这使得它在很大程度上依赖于底层的内存分配器。因此,拥有一个能够有效地处理琐碎任务的内存分配器将显得十分重要,在缺乏此功能的语言中,Flutter 将无法有效地工作。当然 Chrome V8 的 JavaScript 引擎在内存分配上也已经做的很好,事实上 Dart 开发团队的很多成员都是来自Chrome 团队的,所以在内存分配上 Dart 并不能作为超越 JavaScript 的优势,而对于Flutter来说,它需要这样的特性,而 Dart 也正好满足而已。
-
类型安全和空安全。
- 由于 Dart 是类型安全的语言,且 2.12 版本后也支持了空安全特性,所以 Dart 支持静态类型检测,可以在编译前发现一些类型的错误,并排除潜在问题,这一点对于前端开发者来说可能会更具有吸引力。与之不同的,JavaScript 是一个弱类型语言,也因此前端社区出现了很多给 JavaScript 代码添加静态类型检测的扩展语言和工具,如:微软的 TypeScript 以及Facebook 的 Flow。相比之下,Dart 本身就支持静态类型,这是它的一个重要优势。
-
Dart 团队就在你身边。
- 看似不起眼,实则举足轻重。由于有 Dart 团队的积极投入,Flutter 团队可以获得更多、更方便的支持,正如Flutter 官网所述“我们正与 Dart 社区进行密切合作,以改进 Dart 在 Flutter 中的使用。例如,当我们最初采用 Dart 时,该语言并没有提供生成原生二进制文件的工具链(这对于实现可预测的高性能具有很大的帮助),但是现在它实现了,因为 Dart 团队专门为 Flutter 构建了它。同样,Dart VM 之前已经针对吞吐量进行了优化,但团队现在正在优化 VM 的延迟时间,这对于 Flutter 的工作负载更为重要。”
-
Flutter 架构概览,包含其设计层面的核心原则及概念
Flutter 是一个跨平台的 UI 工具集,它的设计初衷,就是允许在各种操作系统上复用同样的代码,例如 iOS 和 Android,同时让应用程序可以直接与底层平台服务进行交互。如此设计是为了让开发者能够在不同的平台上,都能交付拥有原生体验的高性能应用,尽可能地共享复用代码的同时,包容不同平台的差异。
在开发中,Flutter 应用会在一个 VM(程序虚拟机)中运行,从而可以在保留状态且无需重新编译的情况下,热重载相关的更新。对于发行版 (release) ,Flutter 应用程序会直接编译为机器代码(Intel x64 或 ARM 指令集),或者针对 Web 平台的 JavaScript。 Flutter 的框架代码是开源的,遵循 BSD 开源协议,并拥有蓬勃发展的第三方库生态来补充核心库功能。
概览分为以下几部分内容:
- 分层模型:Flutter 的构成要素。
- 响应式用户界面:Flutter 用户界面开发的核心概念。
- widgets 介绍:构建 Flutter 用户界面的基石。
- 渲染过程:Flutter 如何将界面布局转化为像素。
- 平台嵌入层 的概览:让 Flutter 应用可以在移动端及桌面端操作系统执行的代码。
- 将 Flutter 与其他代码进行集成:Flutter 应用可用的各项技术的更多信息。
- Web 支持:Flutter 在浏览器环境中的特性的概述。
Flutter框架结构
- Flutter 被设计为一个可扩展的分层系统,从上到下可以分为三层:框架层、引擎层和嵌入层
-
框架层
- Flutter Framework,即框架层。这是一个纯 Dart实现的 SDK,它实现了一套基础库,自底向上,我们来简单介绍一下:
- 底下两层(Foundation 和 Animation、Painting、Gestures)在 Google 的一些视频中被合并为一个dart UI层,对应的是Flutter中的
dart:ui包,它是 Flutter Engine 暴露的底层UI库,提供动画、手势及绘制能力。 - Rendering 层,即渲染层,这一层是一个抽象的布局层,它依赖于 Dart UI 层,渲染层会构建一棵由可渲染对象的组成的渲染树,当动态更新这些对象时,渲染树会找出变化的部分,然后更新渲染。渲染层可以说是Flutter 框架层中最核心的部分,它除了确定每个渲染对象的位置、大小之外还要进行坐标变换、绘制(调用底层 dart:ui )。
- Widgets 层是 Flutter 提供的的一套基础组件库,在基础组件库之上,Flutter 还提供了 Material 和 Cupertino 两种视觉风格的组件库,它们分别实现了 Material 和 iOS 设计规范。
- Flutter 框架相对较小,因为一些开发者可能会使用到的更高层级的功能已经被拆分到不同的软件包中,使用 Dart 和 Flutter 的核心库实现,其中包括平台插件,例如 camera (opens new window)和 webview (opens new window),以及和平台无关的功能,例如 animations (opens new window)。
-
引擎层
- Engine,即引擎层。毫无疑问是 Flutter 的核心, 该层主要是 C++ 实现,其中包括了 Skia 引擎、Dart 运行时、文字排版引擎等。在代码调用
dart:ui库时,调用最终会走到引擎层,然后实现真正的绘制和显示。
- Engine,即引擎层。毫无疑问是 Flutter 的核心, 该层主要是 C++ 实现,其中包括了 Skia 引擎、Dart 运行时、文字排版引擎等。在代码调用
-
嵌入层
- Embedder,即嵌入层。Flutter 最终渲染、交互是要依赖其所在平台的操作系统 API,嵌入层主要是将 Flutter 引擎 ”安装“ 到特定平台上。嵌入层采用了当前平台的语言编写,例如 Android 使用的是 Java 和 C++, iOS 和 macOS 使用的是 Objective-C 和 Objective-C++,Windows 和 Linux 使用的是 C++。 Flutter 代码可以通过嵌入层,以模块方式集成到现有的应用中,也可以作为应用的主体。Flutter 本身包含了各个常见平台的嵌入层,假如以后 Flutter 要支持新的平台,则需要针对该新的平台编写一个嵌入层。
Flutter开发环境搭建 很多依赖不能直接访问,需科学上网
- 在Linux上搭建Flutter开发环境
- Flutter 依赖下面这些命令行工具
- bash、 curl、 file、 git 2.x、 mkdir、 rm、 unzip、 which、 xz-utils、 zip
- 获取Flutter SDK
# dart sdk集成到flutter sdk,所以不需要再下载dart sdk,也不需要单独配置- 在当前用户根目录下新建soft1文件夹
- cd ~
# 切换到当前用户根目录 - mkdir soft1
# 创建soft1文件夹
- cd ~
- 下载Linux安装包2.10版本到soft1文件下,或其他版本
- 解压
- tar xf flutter_linux_2.10.0-stable.tar.xz
- 环境配置
# 不切换目录 > ls -p ~ -la > vim -p ~/.bashrc- cd ~
# 切换到当前用户根目录 - ls -la
# 查看是否有.bashrc文件,没有则创建.bashrc文件,有则直接追加配置 - vim .bashrc
# 提示无权限,可使用sudo vim .bashrc,或切换root用户,su root- 按下shift键 + i键,进入编辑模式,会显示光标,然后输入以下配置信息
# 修改国内镜像源 export PUB_HOSTED_URL=https://pub.flutter-io.cn export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn # 配置flutter sdk export PATH=~/soft1/flutter/bin:$PATH # 或绝对路径 export PATH=/home/igor/soft1/flutter/bin:$PATH # 打印配置路劲信息,刷新后能看到 echo $PATH- 按下 esc键,退出编辑模式
- 输入 :wq
#保存并退出命令 - 按下回车键,执行以上命令
- source ~/.bashrc
# 刷新配置文件 - which flutter dart
# 校验,查看flutter sdk 和dart sdk路劲 - flutter doctor
# 查看是否还有缺失的依赖需要安装
- cd ~
- 在当前用户根目录下新建soft1文件夹
- Flutter 依赖下面这些命令行工具
- 在macOS上搭建Flutter开发环境
- Flutter 依赖下面这些命令行工具.
bash、mkdir、rm、git、curl、unzip、which
- 获取Flutter SDK
- 环境配置
- cd ~
# 切换到当前用户根目录下 - sudo vi .bashrc_flutter
# 可新建任意名称配置文件,或者在原有的.bashrc或.bash_profile文件内追加以下内容。
export PUB_HOSTED_URL=https://pub.flutter-io.cn export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn export PATH=~/soft/flutter/bin:$PATH- source ~/.bash_flutter
# 如果是新加文件,需要把这行代码添加到/etc/zshrc文件尾部,才能自动读取上面的配置
- cd ~
- 安装或更新xcode到最新版本(当前13.2)
- 设置ios模拟器
- open -a simulator
- 新建模拟器
- simulator界面选择文件 > 选择新建simulator > 设置模拟器名称、型号、系统版本
- Flutter 依赖下面这些命令行工具.
- 安装Homebrew 参考文章
# 是一款Mac OS平台下的软件包管理工具,拥有安装、卸载、更新、查看、搜索等- 终端输入以下命令
/usr/bin/ruby -e "$(curl -fsSL https://cdn.jsdelivr.net/gh/ineo6/homebrew-install/install)"
创建第一个flutter应用
- 使用命令行创建
- flutter create test_app
# 创建test_app应用 - cd test_app
# 切换到应用根目录 - flutter run
# 启动应用
- flutter create test_app
- 使用vscode以debug模式启动应用