flutter 的三棵树
widget tree 和 renderobject tree 以及Element tree
widget tree 也就是我们使用的widget所组成的tree结构。
renderobject tree 是要渲染出来的树结构,并不是widget最终都会生成renderobject tree。
Element tree则是连接介于widget tree 和 renderobject tree 之间的结构,Element tree类似于虚拟dom的功能,它会根据widget tree的改变,然后根据diff算法进行改变,最终影响renderobject tree。
组件widget:不会生成renderobject
- Container();
- Text();
- ...
以Container 为例子,看下Container的继承关系和实现。可以看到它并没有和renderobject有直接的继承关系。
graph TD
Container继承 --> StatelessWidget继承 --> Widget
渲染widget:生成renderobject
- Padding();
- Row();
- ...
以Padding为例子,看一下它的继承关系和实现,它是继承了RenderObjectWidget抽象类,RenderObjectWidget类是有一个抽象方法: createRenderObject的,通过这个抽象方法实现创建RenderObject。 padding -> createRenderObject -> RenderPadding -> RenderBox -> RenderObject。
graph TD
Padding继承 --> SingleChildRenderObjectWidget继承 --> RenderObjectWidget继承 --> Widget
Element Tree
通过上面的介绍可以看到,所有的widget 都会继承Widget()这个类,这个类中有一个抽象方法createElement(),用于创建Element。这也就是说所有的widget都会创建一个Element,不同的widget创建的Element会有所不同,例如在StatelessWidget 中会创建一个StatelessElement()。Element 也可以分为:
-
RenderObjectElement:mount方法-> _widget.createRenderObject
-
ComponentElement:mount方法-> _firstBuild -> rebuild -> performRebuild -> build -> _widget_build。这就说明 ComponentElement 更多的是为了执行build方法,这里的build方法,也就是我们在widget中写的build方法,
StatefulElement 也是继承自 ComponentElement,但是在StatefulElement的构造方法中,调用了_state = widget.createState(), 来创建widget的state, state._widget = widget,这样就可以在state中使用widget字段获取StatefulWidget的变量。
class Bird extends StatefulWidget {
const Bird({ super.key, this.color = const Color(0xFFFFE306), this.child, });
final Color color;
final Widget? child;
@override State<Bird> createState() => _BirdState();
}
class _BirdState extends State<Bird> {
double _size = 1.0;
void grow() { setState(() { _size += 0.1; }); }
@override Widget build(BuildContext context) {
return Container(
color: widget.color, // 使用widget.color
transform: Matrix4.diagonal3Values(_size, _size, 1.0),
child: widget.child, );
}
}
总价
通过对这的了解,简单看一下它们之间的关系,明确flutter的渲染流程。