Flutter(三十五)-有状态和无状态Widget中的Element
我们在上一篇文章中分析了一下Flutter
的三棵树:Widget树
、Element树
和RenderObject树
;这次我们来分析一下,有状态和无状态Widget
中的Element
有什么区别?
StatelessWidget的Element
我们首先看一下在StatelessWidget
中element
的创建方法:
在StatelessWidget
中通过createElement()
方法创建了一个StatelessElement
对象,而StatelessElement
继承自ComponentElement
,那么我们分析一下ComponentElement
发现,在ComponentElement
中有mount
方法,我们在之前的文章中已经分析得知,Widget
创建Element
之后会在Element
中调用mount
方法,那么我们来分析一下此时的mount
方法中做了什么事情:
在mount
方法中,调用了_firstBuild()
方法:
在_firstBuild()
方法中去调用了rebuild()
方法:
之后,我们在rebuild()
方法中会看到一个很重要的方法performRebuild()
方法,继续往下走我们会发现只能看到performRebuild()
方法的定义:
因为此时我们已经进入了Element
类内部,所以我们可以猜测到performRebuild()
的实现应该在Element
的子类中,最后我们在ComponentElement
类中找到了performRebuild()
方法的实现:
在performRebuild()
方法中调用了build()
,在ComponentElement
类中build()
方法也只有定义没有实现,那么我们只能再去ComponentElement
的子类中寻找build
方法的实现,很明显build
的实现应该在StatelessElement
中:
在StatelessElement
中build
的实现为widget.build(this)
,我们通过Debug
断点执行可以看到:
widget
:为MyApp
;this
:为当前StatelessElement
对象;
也就是说,此时是MyApp
在调用build
方法并传递了一个参数StatelessElement
,我们看一下MyApp
的实现:
这就是MyApp
的build
被调用,然后渲染的流程;同时也可以得到BuildContext
其实也就是Element
(我们在之前的文章中使用StatefulElement
也做过如下的操作):
简单来说,
StatelessWidget
初始化时会通过createElement()
方法创建一个StatelessElement
,在createElement()
方法中会调用mount
方法,在mount
方法中会调用Widget
的build
方法进行渲染并将Element自己
传递出去;
StatefulWidget的Element
StatefulWidget
与StatelessWidget
稍有不同,在StatefulWidget
中比StatelessWidget
多了一个createState
方法:
我们先看一下createElement()
方法创建StatefulElement
的实现:
在StatefulElement
的构造方法中,直接调用了widget.createState()
来创建state
对象,同时会将widget
对象保存到state._widget
中(这也是我们在State中能够通过widget来访问Widget中定义的属性的原因
),把Element对象
保存到state._element
中(Widget本身与State对象共用同一个Element
);
最终通过state
对象来调用build
方法:
总结
Flutter
中存在三棵树:Widget树
、Element树
和Render树
;Flutter
引擎针对Render树
中的对象渲染;并非每一个Widget
都有Render树
;- 每一个
Widget
创建时,都会创建一个Element
对象;- 通过
createElement()
方法创建Element
对象,并将Element
对象加入到Element树
中,都会调用mount
方法; RenderElement
主要是创建RenderObject
- 通过
mount
方法创建RenderObject
对象;
- 通过
StatefulElement
继承ComponentElement
- 调用
createState()
方法,创建state
对象; - 将
Widget
赋值给state
对象的_widget
属性; - 通过
state
的build
方法将自己也就是Element
传出去;
- 调用
StatelessElement
继承ComponentElement
- 主要调用
build
方法将Element
传递出去;
- 主要调用
- 通过
转载自:https://juejin.cn/post/7055089994649567239