Flutter学习-29-Flutter的渲染原理
- 渲染原理主要是3个树,
widget
树,render
树,element
树。
1. widget树和render树
Widget树
主要是我们flutter
开发中一层一层的widget
包裹的,比我我们之前例子就是
如果直接渲染widget
是非常耗费性能
的,因为widget
经常发生变化,就会build
。flutter
其实渲染的是render
树,但是不是所有的widget
都继承renderObjectWidget
,比如
Container
就继承 StatelessWidget
在继承widget
而比如Column
继承Flex
Flex
继承 MultiChildRenderObjectWidget
之后继承renderObjectWidget
因此只有继承renderObjectWidget
才能创建renderObject
对象,才能被渲染引擎直接渲染。
renderObjectWidget
我们查看下renderObjectWidget
,主要看下面2个方法,关于createElement
,下面会讲Element树的时候讲。先看下createRenderObject
在我们之前查看Column
继承Flex
的时候有实现这个方法,会返回一个RenderFlex
RenderFlex
继承 RenderBox
最后继承renderObject
所以渲染过程:当Widget的对象继承renderObject
的时候,子类实现父类的方法createRenderObject
创建renderObject
对象 加入render树
中,进行独立渲染。
2. Element树
每一个widget
对象都会建创会都一个Element
对象,我们之前看renderObject
中存在createElement
方法。
我们之前的Flex
继承 MultiChildRenderObjectWidget
,里面实现了该方法
继承
RenderObjectElement
我们之前查看的Column
是继承于RenderObjectWidget
,有的widget直接继承Widget,没有renderObject
,那么是否存在Element
只要是Widget
都会创建一个element
,因此widget树
和element树
是一一对应的。
我们打开debug
模式,创建断点
跳过进入下一步会进入
mount
方法
查看mount
方法
我们会通过
mount
方法把我们创建的element
添加到element
树中。
对于renderObject
,是否也是一样的呢,我们查看之前Column的renderObject
创建
在创建之前会调用
elemen.mount
,说明element创建完
成后才调用createRenderObject
首先创建widget,之后调用createElement
方法创建element
,之后调用amount
方法加入element树
,如果widget
继承renderObjectWidge
t,就会在amount
中创建renderObject
之后加入render树
。
3.Stateless的Element
Stateless
的Element
是StatelessElement
继承
ComponentElement
里面 amount方法,其中有个
_firstBuild
方法,我们继续查看会调用rebuild方法
我们不用关注这些判断,主要看performRebuid
方法,我们shift+command+B
查看实现的地方。
我们查看实现方法主要看build实现
我们的StatelessElement
继承ComponentElement
,我们继续查看子类实现build
的方法。
这里的widget
就是StatelessWidget
,this
就是StatelessElement
实现build
方法
我们在外部调用进行渲染
4. Stateful的Element
相比
StatelessElement
多了一步 _state = widget.createState()
,在创建element
的同时创建了state
,并保存下来。
并把创建的widget和element都赋值给了
state
。
之后调用不同的是通过state
的build
方法,其他的都是和StatelessElement
一样。
5. 总结
每一个Widget
创建都会创建一个Element
对象,通过调用createElement
方法 把创建的Element
加入Element树
中,之后会调用amount
方法,amount
方法会判断,如果widget继承renderObjectWidget
,就会在amount中创建renderObject
之后加入render树
。对于StatelessElement
和StatefulElement
都是继承ComponentElement
,通过调用build
方法,把自己传递出去
。StatefulElement
多了一个createState
。
画个大概的流程图:
转载自:https://juejin.cn/post/7035607966543773703