注:rebulild、layout、paint都是在drawFrame过程中完成的
https://juejin.im/post/5b9a7d396fb9a05d3154fa5a


update child Element的时候的child widget,有时候是要this widget的build方法得到的,有时候直接this widget 的 child属性获取,不同的widget不一样

inflateWidget方法的作用就是创建widget对应的element
Widget实际上就是Element的配置数据,Widget树实际上是一个配置树,而真正的UI渲染树是由Element(或者确切说是由RenderObject)构成;不过,由于Element是通过Widget生成,所以它们之间有对应关系,所以在大多数场景,我们可以宽泛地认为Widget树就是指UI控件树或UI渲染树。
一个Widget对象可以对应多个Element对象。这很好理解,根据同一份配置(Widget),可以创建多个实例(Element)。
从创建到渲染的大体流程是:根据Widget生成Element,然后创建相应的RenderObject并关联到Element.renderObject属性上,最后再通过RenderObject来完成布局排列和绘制。
flutter使用RenderObjects管理传统UI对象的许多职责(例如维护布局的状态)。RenderObjects在帧之间保持不变,flutter的轻量级Widgets告诉框架在状态之间改变RenderObjects。
widget和element一一对应,但是不是所有element都有renderObject。如下代码所示,如果Element不是 RenderObjectElement,则使用的是子树中的element的renderObject。可理解为提供layout或paint相关数据的widget/element自身并不代表一块UI,其是为子控件提供参数的,所以获取子树中的renderObject,通过parentData或者其他方式影响子树中的renderObject的layout/paint。
//Element class
RenderObject get renderObject {
RenderObject result;
void visit(Element element) {
assert(result == null); // this verifies that there's only one child
if (element is RenderObjectElement)
result = element.renderObject;
else
element.visitChildren(visit);
}
visit(this);
return result;
}
Layer
iOS的每一个UIView都有一个layer,flutter的render object不一定存在layer,一般情况下一个renderObject子树都渲染在一个layer上,那么什么renderObject具有layer,子renderObject怎么渲染到这个layer?
- 当一个renderObject的 alwaysNeedsCompositing == true 或者isRepaintBoundary == true,renderOject会有对应的compositing layer
- 子renderObject会对目标layer返回对应的offsetLayer, 目标compositing layer再根据offset合成一个渲染的纹理buffer
flutter框架的四层封装

- dart:ui是最后一个Dart层,它基本上处理与Flutter引擎的通信。
- 大多数时候你会发现Flutter使用的是一个
RenderBox而不是RenderObject,RenderObject中没有坐标系统。这是因为项目背后的人们意识到一个简单的盒子布局协议非常适合构建高性能的UI。想想放在它自己的盒子里的每个小部件,这个盒子被计算出来,然后与其他预先布置好的盒子一起排列。因此,如果布局中只有一个窗口小部件发生更改(例如按钮或开关),则系统只需要重新计算这个相对较小的盒子。 - element持有对Widget和RenderObject.RenderObject负责布局,绘画和交互处理,实例化非常昂贵。element是不可变Widget树和可变RenderObject树之间的粘合剂。Elements主要是对象,它们非常擅长将两个对象相互比较
State的生命周期
- initState
- didChangeDependencies
- didUpdateWidget
- build
- deactivate
- dispose

刚进入页面
- initState
- didChangeDependencies
- build
退出页面
- deactivate
- dispose
deactivate
# StatefulElement
@override
void deactivate() {
_state.deactivate();
super.deactivate();
}
# Element
void deactivateChild(Element child) {
...
owner._inactiveElements.add(child); // this eventually calls child.deactivate()
...
# BuildOwner
final _InactiveElements _inactiveElements = _InactiveElements();
void add(Element element) {
...
if (element._active)
_deactivateRecursively(element);
...
}
static void _deactivateRecursively(Element element) {
...
element.deactivate();
...
}
flutter热重载
flutter热重载会执行reassemble方法,主要流程如下
