flutter中widget三种树之间的源码解读

121 阅读2分钟

Flutter中的树分为WidgetTree ElmentTree RenderObjectTree,三者之间的关系如何?下面对一些结论进行梳理,结合源码解读得出来的结论如下

Flutter Engine(引擎)不会直接根据widget树直接渲染,因为widget是不稳定的,那么他是根据RenderObject Tree渲染的。

在前端中,

  • DOM(文档对象模型)是一个针对HTML和XML文档的API,它为开发人员提供了添加、移除和修改页面的功能。
  • DOM将任何HTML或XML文档描绘成一个层次化的节点树,文档中的每个元素、属性、文本等都代表着树中的一个节点。
  • 因此,DOM可以被认为是HTML或XML文档的编程接口,开发人员可以通过这个接口来操作文档的内容和结构。

widget设计灵感来自于React,通过js生成的html文件 => 虚拟Dom(JS对象) => 真实Dom。

而flutter 是 widget => Element => RenderObject , 每次创建widget,会根据类和对应的key 在Element对象中对比判断是否更新和创建,可以最大程度提升性能。

  • 由于Widget本身是不稳定的,所以需要ElementTree来控制稳定的,RenderTree会根据ElementTree来渲染。
  • 如何理解?通过实例看源码
  1. 是否真的会给我们创建一个Element?
  2. 是否真的会创建Widget?

查找的流程是什么?

  1. 继承关系
    Padding => SingleChildRenderObjectWidget => RenderObjectWidget(有个核心方法createRenderObject) => Widget
    结论: Padding => 实现createRenderObject方法 => SingleChildRenderObjectWidget(creatElement方法)
    每个widget都会创建一个不同的Element,比如statelessWidget和statefulWidget分别创建了statelessElement和statefulWidget.
    拆解问题流程:

  2. 创建自己的widget

  3. 某些widget会创建RenderObject

  4. 每个widget都会创建不同的element对象

  5. flutter引擎会自己调用mount方法, 这个方法在Element类里面可以找到(找了好一会儿)

1).componmentElement: mount() => firstBuild => rebuild => performBuild => build => _widget.build
2).renderObjectElement: mount() => widget.creatRenderObject (挂载) 挂载就是一个Render树下面的节点通过插槽建立联系
3).statefulElement: 构造方法中调用了creatState()
三棵树分别是widget Element(稳定) Render 树
widget分为
组件widget: 不会生成RenderObject
Container()
Text()
渲染widget: 会生成RenderObject
Padding()