Flutter学习-29-Flutter的渲染原理

「这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战」。

  • 渲染原理主要是3个树,widget树,render树,element树。

1. widget树和render树

Widget树主要是我们flutter开发中一层一层的widget包裹的,比我我们之前例子就是

image.png

如果直接渲染widget是非常耗费性能的,因为widget经常发生变化,就会buildflutter其实渲染的是render树,但是不是所有的widget都继承renderObjectWidget,比如 Container就继承 StatelessWidget

image.png

在继承widget image.png

而比如Column 继承Flex

image.png

Flex继承 MultiChildRenderObjectWidget之后继承renderObjectWidget

image.png

因此只有继承renderObjectWidget 才能创建renderObject对象,才能被渲染引擎直接渲染。

  • renderObjectWidget

我们查看下renderObjectWidget,主要看下面2个方法,关于createElement,下面会讲Element树的时候讲。先看下createRenderObject

image.png

在我们之前查看Column继承Flex的时候有实现这个方法,会返回一个RenderFlex

image.png

RenderFlex 继承 RenderBox

image.png

最后继承renderObject

image.png

所以渲染过程:当Widget的对象继承renderObject的时候,子类实现父类的方法createRenderObject创建renderObject对象 加入render树中,进行独立渲染。

2. Element树

每一个widget对象都会建创会都一个Element对象,我们之前看renderObject中存在createElement方法。 我们之前的Flex 继承 MultiChildRenderObjectWidget,里面实现了该方法

image.png 继承 RenderObjectElement

image.png

我们之前查看的Column是继承于RenderObjectWidget ,有的widget直接继承Widget,没有renderObject,那么是否存在Element

image.png

image.png

只要是Widget都会创建一个element,因此widget树element树是一一对应的。

我们打开debug模式,创建断点

image.png 跳过进入下一步会进入mount方法

image.png

查看mount方法 image.png 我们会通过mount方法把我们创建的element添加到element树中。 对于renderObject,是否也是一样的呢,我们查看之前Column的renderObject创建

image.png 在创建之前会调用elemen.mount,说明element创建完成后才调用createRenderObject

image.png

首先创建widget,之后调用createElement方法创建element,之后调用amount方法加入element树,如果widget继承renderObjectWidget,就会在amount中创建renderObject之后加入render树

3.Stateless的Element

image.png

StatelessElementStatelessElement image.png 继承ComponentElement

image.png 里面 amount方法,其中有个_firstBuild方法,我们继续查看会调用rebuild方法

image.png

我们不用关注这些判断,主要看performRebuid方法,我们shift+command+B查看实现的地方。

image.png

我们查看实现方法主要看build实现

image.png

我们的StatelessElement继承ComponentElement,我们继续查看子类实现build的方法。

image.png

这里的widget就是StatelessWidgetthis就是StatelessElement实现build方法

image.png

我们在外部调用进行渲染

image.png

4. Stateful的Element

image.png 相比StatelessElement多了一步 _state = widget.createState(),在创建element的同时创建了state,并保存下来。

image.png 并把创建的widget和element都赋值给了state

image.png

之后调用不同的是通过statebuild方法,其他的都是和StatelessElement一样。

5. 总结

每一个Widget创建都会创建一个Element对象,通过调用createElement方法 把创建的Element加入Element树中,之后会调用amount方法,amount方法会判断,如果widget继承renderObjectWidget,就会在amount中创建renderObject之后加入render树。对于StatelessElementStatefulElement都是继承ComponentElement,通过调用build方法,把自己传递出去StatefulElement多了一个createState
画个大概的流程图:

flutter渲染-2.jpg

猜你喜欢

转载自juejin.im/post/7035607966543773703
今日推荐