Widget
Widget用来保存Element的配置信息,本身为不可变,Element根据Widget内保存的配置信息来管理渲染树,可以多次插入Widget树中,每次Element都要重新装载Widget。 Widget内key属性用来决定依赖这个Widget的Element在Element树中更新或移除。
abstract class Widget {
const Widget({ this.key });
final Key key;
@protected
Element createElement();
static bool canUpdate(Widget oldWidget, Widget newWidget) {
return oldWidget.runtimeType == newWidget.runtimeType
&& oldWidget.key == newWidget.key;
}
}
Element
Element可以理解为Widget的实例,并且关联在Widget树特定位置上。 Element可以通过widget.createRenderObject获取到RenderObject对象,所以Element同时包含RenderObject和Widget。 Widget不可变,一个Widget可以同时配置多个子Widget树,这时Element用来代表特定位置的Widget。 Element是可变的,子节点数量可以是一个或多个。 生命周期: 1.Flutter framework通过Widget.createElement来创建一个Element。 2.当Widget创建并插入到Widget树中时,framework就会通过mount方法来把这个Widget创建并关联的Element插入到Element树中(其父Element会给出一个位置)。 3.通过AttachRenderObject方法来将RenderObjects关联到Render树上,Widget就会显示在屏幕上。 4.每当执行Rebuild方法,Widget代表的配置信息改变时,如果新老Widget的RuntimeType和key相同,framework就会调用Widget的update方法;如果不同就要先unmounting然后重新装载Widget。 5.当父Element想要移除子Element时,可以通过deactivateChild把子Element从树中移除,然后将子Element加入不活跃列表中,接着framework会将子Element从屏幕中移除。
RenderObject
RenderObject作为渲染树中的对象存在。不会定义约束关系,不对控件的布局管理。在Widget里创建。RenderObject包含parentData属性,用来保存child节点的特定信息。其主要作用就是绘制和布局,点击检测和大小计算。
abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin implements HitTestTarget {
ParentData parentData;
Constraints _constraints;
void layout(Constraints constraints, { bool parentUsesSize = false }) {
}
void paint(PaintingContext context, Offset offset) { }
void performLayout();
void markNeedsPaint() {
}
}
|