Flutter UI架构
简述
Flutter使用dart语言来构建维护UI数据,然后通过Impeller渲染引擎来进行UI渲染,在学习源码之前,我们先来了解一下Flutter的UI框架的大体架构,这样后面再学习源码可以事半功倍。
使用Flutter开发,主要接触的都是Widget,在业务层实现UI时会构建一个Widget树,然后会根据Widget树构建一套Element,最终Element还会构造RenderObject,Widget树和Element树是一对一的,而Element和RenderObject却不是一对一的,因为有一些组件只是用作结构控制,并没有渲染能力。
RenderObject还会持有layer,最终会构成一个LayerTree,然后Flutter engine会将LayerTree的信息使用渲染引擎渲染合成。
这里涉及的代码逻辑分两个仓库,flutter和engine,其中flutter仓库包含框架,而engine仓库包含渲染引擎,这两个的关系有点类似app和SurfaceFlinger。
其中engine的功能类似于SurfaceFlinger,会进行layer合成,而flutter则负责管理上层UI树结构,描述app UI怎么构建。
概念
Widget
Widget是用于描述UI配置信息的,例如布局,样式,交互之类的,Widget有几种类型
- StatefulWidget
- StatelessWidget
- RenderObjectWidget
- LeafRenderObjectWidget
- SingleChildRenderObjectWidget
- MultiChildRenderObjectWidget
- ProxyWidget
这里StatefulWidget和StatelessWidget分别为有状态组件和无状态组件,但是他们都没有RenderObject,也就是说没有渲染能力,他们的作用是组合,往往里面都会包含RenderObjectWidget。
而RenderObjectWidget是拥有渲染能力的组件。
ProxyWidget则用于承接父节点和子节点,一般用来共享数据。
Element
Element也有非常多的子类,每种Widget都会构造自己的Element,比如StatefulWidget会构建StatefulElement,StatefulElement是用于记录Widget运行时候的信息,管理Widget生命周期。
RenderObject
RenderObject用于负责渲染逻辑,计算尺寸,布局,绘制。
带有渲染能力的Element都会关联一个RenderObject,而RenderObject有performResize,performLayout,paint等抽象方法,类似于Android的onMeasure,onLayout,onDraw。
其中paint会有一个参数PaintingContext,PaintingContext上下文包含了操作layer的接口能力,其中有的layer可以构建Canvas,后续就可以使用Canvas接口调用渲染引擎渲染绘制
Layer
上面提到过RenderObject在paint的时候会有一个PaintingContext,PaintingContext里面的接口可以构建各种layer,其中PictureLayer可以使用canvas进行渲染,在dart层的Layer会在C++层有一套映射,最终合成时会使用C++层的映射的LayerTree,layer的概念也类似于图层,将组件渲染分图层,这样可以更好的复用,没有改动的图层的就可以完全复用。
小结
本节主要介绍了一下Flutter UI架构核心概念,了解这些概念之后学习Flutter UI框架的代码会比较容易看懂,下一节我们会来看代码学习Flutter UI框架。