查看抽象类实现快捷键: command+option+b
Flutter 渲染原理分析,针对Widget、Element、renderObject进行分析。并详细阐述三者关系
- 自己写Widget
- 部分Widget会生成RederObject进行渲染
- 每一个Widget都会生成对应的Element,每次挂载到树上,都会生成一个Element
4.1 ComponElement会调用mount方法, mout -> firstBuild -> rebuild -> performBuild -> build -> _widget.build
4.2 RenderObjectElement: mount -> widger.createRenderObject
4.3 StatefulElement: 构造方法中 widger.createState()
Widget 到 RenderObject过程
创建过程是要实现RenderObjectWidget内部的createRenderObject方法.具体在Padding来看,是在Padding内部进行了实现
class Padding extends SingleChildRenderObjectWidget {
@override
RenderPadding createRenderObject(BuildContext context) {
return RenderPadding(
padding: padding,
textDirection: Directionality.maybeOf(context),
);
}
}
RenderPadding --> RenderShiftedBox --> RenderBox --> RenderObject
具体调用地方待查看?
Widget 到 Element 的过程
可以看出抽象方法是在Widget里面定义的,是所有抽象方法的根,也就是说无论是渲染Widget和非渲染Widget(所有Widget)都要实现这个方法. 创建一个Element
| 非渲染Widget | 渲染Widget |
|---|---|
| StlessElement | RenderElement |
| StatefulElement |
mount方法
调用顺序:mount -> firstBuild -> rebuild -> performBuild -> build -> _widget.build
Element 里面的 mount
/// Add this element to the tree in the given slot of the given parent.
/// The framework calls this function when a newly created element is added to the tree
/// for the first time.
@mustCallSuper
void mount(Element? parent, Object? newSlot) {
}
ComponentElement中 (stless、stful都是继承ComponentElement)
/// **********Class ComponentElement
@override
void mount(Element? parent, Object? newSlot) {
super.mount(parent, newSlot);
_firstBuild();
}
void _firstBuild() {
// StatefulElement overrides this to also call state.didChangeDependencies.
rebuild(); // This eventually calls performRebuild.
}
/// **********Class Element
void rebuild() {
performRebuild();
}
// 抽象方法,查看具体(command+option+b)实现在ComponentElement中
void performRebuild();
/// **********Class ComponentElement
void performRebuild() {
built = build();
}
// 抽象方法
@protected
Widget build();
/// ***********Class StlessElement
// widget是创建Element时候,传入的
Widget build() => (widget as StatelessWidget).build(this);
RenderObjectElement 中
void mount(Element? parent, Object? newSlot) {
_renderObject = (widget as RenderObjectWidget).createRenderObject(this);
}
StatefulElement中
StatefulElement(StatefulWidget widget): _state = widget.createState(),
super(widget) {
// 将widget进行了赋值操作
state._widget = widget;
}
// stful这里的build,可以看出是调用state的build方法,同时将Element传出去
@override
Widget build() => state.build(this);
可以看出,Element内部,既有Widget也包含RenderObject,还包含state
// StlessElement
Widget build() => (widget as StatelessWidget).build(this);
// RenderObjectElement
_renderObject = (widget as RenderObjectWidget).createRenderObject(this);
// StatefulElement
StatefulElement(StatefulWidget widget): _state = widget.createState(),
super(widget) {
}
总结:StlessWidget 调用 CreateElement方法,创建ELement, Element调用mount方法,mount方法内部调用Widget的build方法