古话说:“水之积也不厚,则其负大舟也无力”,想要深入框架和语言需要打好基础,我们了解一下Flutter的核心渲染原则Flutter渲染三棵树原理
可以用网上看到的博主举的例子形容得非常恰当
Widget(产品经理),element(UI),renderObject(程序员),产品经理将我们的项目蓝图构建出来,描述给UI,UI将产品经理的想法,告诉程序员,程序员根据设计图开发程序,这就是简单的三棵树之间的关系。
一、原理介绍
Flutter中一切皆是Widget,可以通过下面一张图来熟悉一下具体的三棵树。
官网三棵树描述官网介绍Flutter框架的的处理流程
1.根据Widget树生成一个Element树,Element树中的节点都继承自Element类。
2.根据Element树生成Render树(渲染树),渲染树中的节点都继承自RenderObject类。
3.根据渲染树生成Layer树,然后上屏显示,Layer树中的节点都继承自Layer类。
我们可以认为Flutter的UI系统包含三棵树:Widget树、Element树、渲染树。
依赖关系为:根据Widget树生成Element树,再依赖于Element树生成RenderObject 树
三棵树的具体介绍:
Widget:只是一个配置,里面存储的是有关视图渲染的配置信息,包括布局、渲染属性、事件响应信息等。是不可变的,主要负责描述UI的属性和布局,不负责实际的渲染绘制,所以创建成本很低
Element 是分离 WidgetTree 和真正的渲染对象的中间层, WidgetTree 用来描述对应的Element 属性,同时持有Widget和RenderObject,存放上下文信息,通过它来遍历视图树,支撑UI结构。
RenderObject (渲染树)用于应用界面的布局和绘制,负责真正的渲染,保存了元素的大小,布局等信息,实例化一个 RenderObject 是非常耗能的
二、三棵树创建顺序:
1)Flutter会构建Widget的Widgets树;
2)Flutter遍历Widget树,然后根据其中的Widget调用createElement()来创建相应的Element对象, 最后将这些对象组建成Element树;
3)接下来会创建第三个树,这个树中包含了与Widget对应的Element通过createRenderObject()创建 的RenderObject;
三、三棵树作用
Widget树:存放渲染内容、视图布局信息;
Element树:存放上下文,通过 Element 遍历视图树,Element 同时持有 Widget 和RenderObject;
RenderObject树:根据 Widget 的布局属性进行 layout 和绘制;
Flutter中几乎所有的对象都是Widget,而widget又分为StatelessWidget和StatefulWidget。
StatelessWidget:无中间状态的Widget,一旦创建便不可更改,只能再重新创建
StatefulWidget:存在中间状态,同时引入了State来存放中间状态,通过调用state.setState()进行更新
1、State
通常一个StatefulWidget会对应一个State,State中有两个常用的属性Widget、context
Widget:与state相绑定的Widget实例 context:StatefulWidget所对应的BuildContext。
注意:Flutter会调用mount方法,调用createRanderObject方法。同时有一个属性为mounted变量,mounted变量可以判断当前State对象是否已经被插入到树中,在进行调用state.setState()进行更新的时候需要确认mounted为true的情况。
2、BuildContext
大家对于BuildContext肯定见得比较多,不管StatelessWidget和StatefulWidget里面都有BuildContext。
并且在很多组件中都需要BuildContext,那么BuildContext具体是什么呢,BuildContext是Element的实例
四、三棵树联系
1、每一个Widget都会创建一个Element对象;
2、隐式调用createElement方法,Element加入Element树中(它会创建三种Element);
3、继承RenderObjectWidget的Widget会创建RenderElement;
RenderElement主要是创建RenderObject对象,分为两步:创建RanderElement,Flutter会调用mount方法,调用createRanderObject方法。 4、StatefulWidget会创建StatefulElement,StatefulElement继承ComponentElement;
createElement 方法中,调用createState方法,持有state。将自己(Element)和widget给state持有。
创建流程:
a、widget调用createState方法,创建State;
b、将Widget赋值给state;
c、调用state的build方法 并且将自己(Element)传出去。
5、StatelessWidget会创建StatelessElement,StatelessElement继承ComponentElement;
主要就是调用build方法 并且将自己(Element)传出去。
几个知识点:
1、Element树是一个管理widget树和Rander树的上下文,build方法中context,本质就是Element。
2、Flutter的渲染是增量渲染,Element是可以被复用的;
3、widget不在widget树中就会被释放,想要不被释放,一定要持有在widget树中;
网友评论