Flutter核心概念与学习路线

Flutter的核心Skia与Dart

Flutter官网:https://flutterchina.club/
Dart官网:https://dart.cn/

Skia: 图像渲染引擎

向GPU提供视图数据。

Skia是C++开发,性能强悍的2D图像回执引擎。05年被Google收购。Skia在图形转换、文字渲染、位图渲染表象卓越,提供了友好的API。

SKia目前是Android官方的图像渲染引擎,安卓SDK无需内嵌Skia引擎就可以获得Skia支持。

对于iOS来说,flutter的SDK已经内嵌了Skia渲染引擎,代替了iOS的渲染引擎。因此构建出来的iOS包要比安卓的包大。

由于底层渲染都是通过Skia渲染的,所以Skia保证了同一套代码在安卓和iOS有一致的渲染效果。

Dart语言

语言特性:同时支持JIT和AOT。

界面布局:通过 Dart 编码来定义,声明式编程布局。不需要可视化界面构建器,使用热重载看效果。

线程模型:单线程模型,不存在资源竞争和状态同步。所以Dart中没有线程的概念,只有隔离区的概念Isolate避免了抢占式调度和共享内存。

包管理:有完善的包管理机制。


Flutter架构

image.png

从下到上分为3层:

Embedder:操作系统适配层,实现了渲染Surface 设置,线程设置,以及平台插件等平台相关特性的适配

Engine:主要包含 Skia、Dart 和 Text,实现了 Flutter 的渲染引擎、文字排版、事件处理和 Dart 运行时等功能。Skia 和 Text 为上层接口提供了调用底层渲染和排版的能力,Dart 则为 Flutter 提供了运行时调用 Dart 和渲染引擎的能力。而 Engine 层的作用,则是将它们组合起来,从它们生成的数据中实现视图渲染。

Framework:是一个用 Dart 实现的 UI SDK包含了动画、图形绘制和手势识别等功能。为了在绘制控件等固定样式的图形时提供更直观、更方便的接口,Flutter 还基于这些基础能力,根据 Material 和 Cupertino 两种视觉设计风格封装了一套 UI 组件库。我们在开发 Flutter 的时候,可以直接使用这些组件库。

控件树(Widgets)--->渲染树(渲染对象)[布局-绘制-合成-渲染]

布局:深度优先遍历--->决定各渲染对象在屏幕上的尺寸和位置

渲染对象接受父对象的布局约束参数,决定自己的大小。然后父对象按照控件逻辑决定各个子对象的位置。

布局边界:防止子节点变化导致整个控件树重新布局。可以在某些节点自动或手动设置布局边界,边界内对象的布局变动不会影响边界外的对象。

绘制:深度优先,把所有渲染对象绘制到不同图层。总是先绘制自身再绘制子节点。

重绘边界:在重绘边界内,Flutter 会强制切换新的图层,这样就可以避免边界内外的互相影响,避免无关内容置于同一图层引起不必要的重绘。重绘边界的一个典型场景是 Scrollview。ScrollView 滚动的时候需要刷新视图内容,从而触发内容重绘。而当滚动内容重绘时,一般情况下其他内容是不需要重绘的,这时候重绘边界就派上用场了。

合成:终端设备的页面越来越复杂,因此 Flutter 的渲染树层级通常很多,直接交付给渲染引擎进行多图层渲染,可能会出现大量渲染内容的重复绘制,所以还需要先进行一次图层合成,即将所有的图层根据大小、层级、透明度等规则计算出最终的显示效果,将相同的图层归类合并,简化渲染树,提高渲染效率。

渲染:合并完成后,Flutter 会将几何图层数据交由 Skia 引擎加工成二维图像数据,最终交由 GPU 进行渲染,完成界面的展示


学习路线


image-20211023161421854.png

Flutter工程:

image-20211023162318281.png

Flutter 工程实际上就是一个同时内嵌了 Android 和 iOS 原生子工程的父工程:我们在 lib 目录下进行 Flutter 代码的开发,而某些特殊场景下的原生功能,则在对应的 Android 和 iOS 工程中提供相应的代码实现,供对应的 Flutter 代码引用。Flutter 会将相关的依赖和构建产物注入这两个子工程,最终集成到各自的项目中。而我们开发的 Flutter 代码,最终则会以原生工程的形式运行。

一切皆组件:在 Flutter 中,Widget 是整个视图描述的基础,是 Flutter 功能的抽象描述,是视图的配置信息,同样也是数据的映射,是 Flutter 开发框架中最基本的概念。在 Flutter 的世界里,包括应用(Application)、视图(View)、视图控制器(View Controller)、活动(Activity)、应用(Application)、布局(Layout)等在内的概念,都建立在 Widget 之上,Flutter 的核心设计思想便是一切皆 Widget

Widget 是组件视觉效果的封装,是 UI 界面的载体,使用build方法来构建UI。

常用组件:

StatelessWidget 无状态组件,提供了build接口构建UI

StatefulWidget:有状态组件,提供createState创建状态,State当中提供了build构建UI

有状态和无状态提供不同接口的原因是:组件需要依赖数据完成构建。而有状态的组件数据可能频繁发生变化,由状态去创建组件,用数据来驱动更新,而不是直接操作UI更新视觉。

setState 方法是 Flutter 以数据驱动视图更新的关键函数,它会通知 Flutter 框架刷新页面(执行build方法,根据状态重新构建页面),状态的更改一定要配合使用 setState。Widget 只是视图的“配置信息”,是数据的映射,是“只读”的。对于 StatefulWidget 而言,当数据改变的时候,我们需要重新创建 Widget 去更新界面,这也就意味着 Widget 的创建销毁会非常频繁。为此,Flutter 对这个机制做了优化,其框架内部会通过一个中间层去收敛上层 UI 配置对底层真实渲染的改动,从而最大程度降低对真实渲染视图的修改,提高渲染效率,而不是上层 UI 配置变了就需要销毁整个渲染视图树重建。

MaterialApp 类是对构建 material 设计风格应用的组件封装框架,里面还有很多可配置的属性,比如应用主题、应用名称、语言标识符、组件路由等。

Scaffold:Material 库中提供的页面(脚手架)布局结构,它包含 AppBar、Body,以及 FloatingActionButton等。

命令式的 UI 编程风格:手动创建 UI 组件,在需要更改 UI 时调用其方法修改视觉属性。而 Flutter 采用声明式 UI 设计,我们只需要描述当前的 UI 状态(即 State)即可,不同 UI 状态的视觉变更由 Flutter 在底层完成。

虽然命令式的 UI 编程风格更直观,但声明式 UI 编程方式的好处是,可以让我们把复杂的视图操作细节交给框架去完成,这样一来不仅可以提高我们的效率,也可以让我们专注于整个应用和页面的结构和功能。

你可能感兴趣的:(Flutter核心概念与学习路线)