flutter

Flutter

Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作。在全世界,Flutter 正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
中文官网:
https://flutterchina.club/setup-macos/
https://flutter-io.cn/

第三方库 可以理解为npm
https://pub.dartlang.org/flutter

环境搭建\入门\填坑指南
https://blog.csdn.net/hekaiyou/article/details/52874796
https://www.jianshu.com/p/399c01657920

国内Flutter论坛
http://flutter-dev.cn/

Dart\Flutter 扩展插件
https://dartcode.org/releases/v2-19/

Flutter入门实例
https://juejin.im/post/5b31d776e51d455e2b5ab253

Widget组件介绍
https://juejin.im/post/5bab35ff5188255c3272c228

GitHub-Flutter聚集地
https://github.com/xitu/awesome-flutter

介绍

** 概念 **

  1. Flutter 是一个移动应用程序的软件开发工具包(SDK),具有以下特征:

    跨平台应用的框架,没有使用 WebView 或者系统平台自带的控件,使用自身的高性能渲染引擎自绘
    简化版的浏览器,最大限度在 android 和 ios 上统一 UI,包括业务逻辑和用户体验
    开发语言使用 dart,结合 C, C++, 和 Skia(2D 渲染引擎)构建
    支持 hot reload,包含着完整的控件和工具链

    一切皆控件,控件是每个 Flutter 应用程序的基本构建块,与分离视图、控制器、布局和其他属性的框架不同,Flutter 具有一致的统一对象模型:控件。一个控件可以定义:结构元素(比如按钮或菜单)、风格元素(比如字体或颜色方案)、布局的方面(比如填充)、一些业务逻辑等

    与 React 理念相同,都是组合大于继承,控件本身通常由许多小型、单用途的控件组成,结合起来产生强大的效果,类的层次结构是扁平的,以最大化可能的组合数量

    强化版的 WebView,框架仅提供一个 View 层,大部分功能要依赖原生
    目前只能够运行大部分 Dart 代码(不能引入 dart:mirrors 或 dart:html 库)

** 优势 **

  1. 宏观上:

    Flutter 能够提供优美的 UI 和流畅的使用体验
    Flutter 降低了开发 App 的门槛,加速移动应用的开发速度,并且能够降低同时开发 Android 和 iOS 应用的成本和复杂度
    Flutter 能够轻松做出原型并且能够保持相当高还原度

  2. 微观上:

    高效率,用一套代码库就能开发 iOS 和 Android 应用
    使用新型的、表现力强的语言和声明式的方法,用更少的代码来做更多的事情
    可以在应用程序运行时更改代码并重新加载查看效果,也就是热重新加载
    修复崩溃时可以从应用程序停止的位置继续调试
    创建美观、高度定制的用户体验
    Flutter 框架内置了一组丰富的质感设计控件
    实现定制、美观、品牌驱动的设计,而不受 OEM 控件集的限制
    深度优化,移动优先的 2D 渲染引擎而且对文本支持非常出色
    react 风格的框架
    支持单元和集成测试的 API
    支持与系统平台和第三方 SDK 交互的插件 API
    支持 Windows,Mac 和 Linux 的 Headless test runner

运行机制

Flutter 应用运行在一个用 C++ 写的引擎中,Flutter 应用可以看做是一个游戏 App,代码都是在引擎中运行。

** Android **

引擎的 C 或 C++代码是由 Android NDK 编译的,而框架的主要代码和应用的代码由 Dart compiler 编译成 native code 执行的。

对于 Android 应用来说,Flutter 框架在引擎中实现了一个继承于 SurfaceView 的 FlutterView。用户所看到的 UI 都是在这个 SurfaceView 中显示。如果要和原生平台功能交互,则可以在 Activity 中使用 FlutterView,并通过 Flutter 提供的消息 API 和原生平台收发消息。

** ios **

引擎的 C 或 C++代码是由 LLVM 编译的,而所有 Dart 的代码会被 AOT 编译成 native code,整个 APP 运行时使用的是机器指令(并不是拦截器)。

架构

** 层次描述 **

Flutter 的框架分为 Framework 和 Engine 两层,应用是基于 Framework 层开发的,Framework 负责渲染中的 Build,Layout,Paint,生成 Layer 等环节。Engine 层是 C++实现的渲染引擎,负责把 Framework 生成的 Layer 组合,生成纹理,然后通过 Open GL 接口向 GPU 提交渲染数据。

** 图形管道 **

** 渲染管道 **

当需要更新 UI 的时候,Framework 通知 Engine,Engine 会等到下个 Vsync 信号到达的时候,会通知 Framework,然后 Framework 会进行 animations, build,layout,compositing,paint,最后生成 layer 提交给 Engine。Engine 会把 layer 进行组合,生成纹理,最后通过 Open Gl 接口提交数据给 GPU, GPU 经过处理后在显示器上面显示。

当应用调用 setState 后,经过 Framework 一连串的调用后,最终调用 scheduleFrame 来通知 Engine 需要更新 UI,Engine 就会在下个 vSync 到达的时候通过调用_drawFrame 来通知 Framework,然后 Framework 就会通过 BuildOwner 进行 Build 和 PipelineOwner 进行 Layout,Paint,最后把生成 Layer,组合成 Scene 提交给 Engine。接下来我们从代码中分析一下,这些环节具体是怎么样实现的。首先从 Engine 回调 Framework 的入口开始。

在 Flutter 应用开发中,无状态的 widget 是通过 StatelessWidget 的 build 方法构建 UI,有状态的 widget 是通过 State 的 build 方法构建 UI。现在具体分析一下从 setState 调用后到调用自定义 State 的 build 的流程是怎样的(现在只分析有状态的 widget 渲染过程)。

在 Flutter 中应用中,是使用支持 layout 的 widget 来实现布局的,支持 layout 的 wiget 有 Container,Padding,Align 等等,强大又简易。在渲染流程中,在 widget build 后会进入 layout 环节,下面具体分析一下 layout 的实现,layout 入口是 flushLayout。

应用场景

Flutter 支持 ios android Tv 嵌入式系列开发

了解** Widget **组件

在 Flutter 中,我们平时自定义的 widget,一般都是继承自 StatefulWidget 或 StatelessWidget(并不是只有这两种),这两种 widget 也是目前最常用的两种。如果一个控件自身状态不会去改变,创建了就直接显示,不会有色值、大小或者其他属性的变化,这种 widget 一般都是继承自 StatelessWidget,常见的有 Container、ScrollView 等。如果一个控件需要动态的去改变或者相应一些状态,例如点击态、色值、内容区域等,那么一般都是继承自 StatefulWidget,常见的有 CheckBox、AppBar、TabBar 等。其实单纯的从名字也可以看出这两种 widget 的区别,这两种 widget 都是继承自 Widget 类。

Widget 类在 Flutter 中是非常重要的,继承自 Widget 类的有 PreferredSizeWidget、ProxyWidget、RenderObjectWidget、StatefulWidget、StatelessWidget。我们日常使用的绝大部分 widget 都是继承自 Widget 类,

生命周期

** 控件生命周期 **

** 状态生命周期 **

** 生命周期有四种状态: **

created:当 State 对象被创建时候,State.initState 方法会被调用;

initialized:当 State 对象被创建,但还没有准备构建时,State.didChangeDependencies 在这个时候会被调用;

ready:State 对象已经准备好了构建,State.dispose 没有被调用的时候;

defunct:State.dispose 被调用后,State 对象不能够被构建。

** 完整生命周期如下: **

  1. 创建一个 State 对象时,会调用 StatefulWidget.createState;

  2. 和一个 BuildContext 相关联,可以认为被加载了(mounted);

  3. 调用 initState;

  4. 调用 didChangeDependencies;

  5. 经过上述步骤,State 对象被完全的初始化了,调用 build;

  6. 如果有需要,会调用 didUpdateWidget;

  7. 如果处在开发模式,热加载会调用 reassemble;

  8. 如果它的子树(subtree)包含需要被移除的 State 对象,会调用 deactivate;

  9. 调用 dispose,State 对象以后都不会被构建;

  10. 当调用了 dispose,State 对象处于未加载(unmounted),已经被 dispose 的 State 对象没有办法被重新加载(remount)。

环境搭建

  1. 克隆 Flutter 仓库到本地

git clone -b master https://github.com/flutter/flutter.git

  1. 配置环境变量
1
2
3
4
export PUB_HOSTED_URL=https://pub.flutter-io.cn //国内用户需要设置
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn //国内用户需要设置
export FLUTTER_HOME= // 设置Flutter SDK 目录
export PATH=$FLUTTER_HOM/bin:$PATH
  1. 执行命令检测 Flutter 依赖, 需要科学上网(这样会自动下载)

flutter doctor