深色模式
Element 源码分析
Element分类
先看一下Element
类的继承关系:
Element 分为2类:
组合型Element
ComponentElement
及其子类,负责组合Element Tree渲染型Element
RenderObjectElement
及其子类,参与渲染
核心方法分析
inflateWidget()
parent 根据 newWidget 创建 child。
dart
Element inflateWidget(Widget newWidget, Object? newSlot) {
final Key? key = newWidget.key;
if (key is GlobalKey) {
final Element? newChild = _retakeInactiveElement(key, newWidget);
if (newChild != null) {
try {
newChild._activateWithParent(this, newSlot);
} catch (_) {
try {
deactivateChild(newChild);
} catch (_) {
}
rethrow;
}
final Element? updatedChild = updateChild(newChild, newWidget, newSlot);
return updatedChild!;
}
}
final Element newChild = newWidget.createElement();
newChild.mount(this, newSlot);
return newChild;
}
dart
Element inflateWidget(Widget newWidget, Object? newSlot) {
final Key? key = newWidget.key;
if (key is GlobalKey) {
final Element? newChild = _retakeInactiveElement(key, newWidget);
if (newChild != null) {
try {
newChild._activateWithParent(this, newSlot);
} catch (_) {
try {
deactivateChild(newChild);
} catch (_) {
}
rethrow;
}
final Element? updatedChild = updateChild(newChild, newWidget, newSlot);
return updatedChild!;
}
}
final Element newChild = newWidget.createElement();
newChild.mount(this, newSlot);
return newChild;
}
是一个模板方法,定义在Element类中,没有被重写。
作用:
根据 Widget 创建 Element
调用场景:
- 新增Widget
- Widget完全改变
mount()
element 把自己挂载到 parent 下面。
dart
void mount(Element? parent, Object? newSlot) {
_parent = parent;
_slot = newSlot;
_lifecycleState = _ElementLifecycle.active;
_depth = 1 + (_parent?.depth ?? 0);
if (parent != null) {
_owner = parent.owner;
_parentBuildScope = parent.buildScope;
}
final Key? key = widget.key;
if (key is GlobalKey) {
owner!._registerGlobalKey(key, this);
}
_updateInheritance();
attachNotificationTree();
}
dart
@override
void mount(Element? parent, Object? newSlot) {
super.mount(parent, newSlot);
_firstBuild();
}
dart
@override
void mount(Element? parent, Object? newSlot) {
super.mount(parent, newSlot);
_renderObject = (widget as RenderObjectWidget).createRenderObject(this);
attachRenderObject(newSlot);
super.performRebuild(); // clears the "dirty" flag
}
dart
@override
void mount(Element? parent, Object? newSlot) {
super.mount(parent, newSlot);
_child = updateChild(_child, (widget as SingleChildRenderObjectWidget).child, null);
}
dart
@override
void mount(Element? parent, Object? newSlot) {
super.mount(parent, newSlot);
final MultiChildRenderObjectWidget multiChildRenderObjectWidget =
widget as MultiChildRenderObjectWidget;
final List<Element> children = List<Element>.filled(
multiChildRenderObjectWidget.children.length,
_NullElement.instance,
);
Element? previousChild;
for (int i = 0; i < children.length; i += 1) {
final Element newChild = inflateWidget(
multiChildRenderObjectWidget.children[i],
IndexedSlot<Element?>(i, previousChild),
);
children[i] = newChild;
previousChild = newChild;
}
_children = children;
}
作用:
把 Element 挂载到 parent 下面。
updateChild()
element 更新 child。
dart
Element? updateChild(Element? child, Widget? newWidget, Object? newSlot) {
// ...
}
方法作用:
parent element 通过这个方法,更新它的 child element。
方法参数说明:
child
当前
Element
的子节结。child
为空,说明当前这个 parent element 没有子节点。newWidget
子节点对应的
Widget
。newWidget
为空,说明 child element 对应的Widget
被移除了。
方法注释:
newWidget == null | newWidget != null | |
---|---|---|
child == null | Returns null. | Returns new [Element]. |
child != null | Old child is removed, returns null. | Old child updated if possible, returns child or new [Element]. |
源码定位:
newWidget
为空说明 child element 对应的
Widget
被移除了(这时如果 child 非空要移除 child ),返回 null 。newWidget非空,child非空,newWidget与child.widget相等
说明 child element 对应的Widget无变化,但可能需要移动 child 的位置(单子节点的 parent element 不存在移动 child 位置的情况)。
newWidget非空,child非空,newWidget与child.widget对比以后可更新
说明可以用newWidget去配置已有的 child,那么调用 child.update()。
并且仍然要考虑child的位置发生变化。
newWidget非空,child非空,newWidget与child.widget根本对不上
说明child对应的Widget完全变了,能移除child,重新创建一个child element。
newWidget非空,child为空
说明是新插入Widget的场景,直接创建一个child element。
把以上5点在源码中标记一下:
dart
Element? updateChild(Element? child, Widget? newWidget, Object? newSlot) {
if (newWidget == null) {
if (child != null) {
deactivateChild(child);
}
return null;
}
final Element newChild;
if (child != null) {
bool hasSameSuperclass = true;
if (hasSameSuperclass && child.widget == newWidget) {
if (child.slot != newSlot) {
updateSlotForChild(child, newSlot);
}
newChild = child;
} else if (hasSameSuperclass && Widget.canUpdate(child.widget, newWidget)) {
if (child.slot != newSlot) {
updateSlotForChild(child, newSlot);
}
child.update(newWidget);
newChild = child;
} else {
deactivateChild(child);
newChild = inflateWidget(newWidget, newSlot);
}
} else {
newChild = inflateWidget(newWidget, newSlot);
}
return newChild;
}
dart
Element? updateChild(Element? child, Widget? newWidget, Object? newSlot) {
if (newWidget == null) {
if (child != null) {
deactivateChild(child);
}
return null;
}
final Element newChild;
if (child != null) {
bool hasSameSuperclass = true;
if (hasSameSuperclass && child.widget == newWidget) {
if (child.slot != newSlot) {
updateSlotForChild(child, newSlot);
}
newChild = child;
} else if (hasSameSuperclass && Widget.canUpdate(child.widget, newWidget)) {
if (child.slot != newSlot) {
updateSlotForChild(child, newSlot);
}
child.update(newWidget);
newChild = child;
} else {
deactivateChild(child);
newChild = inflateWidget(newWidget, newSlot);
}
} else {
newChild = inflateWidget(newWidget, newSlot);
}
return newChild;
}
dart
Element? updateChild(Element? child, Widget? newWidget, Object? newSlot) {
if (newWidget == null) {
if (child != null) {
deactivateChild(child);
}
return null;
}
final Element newChild;
if (child != null) {
bool hasSameSuperclass = true;
if (hasSameSuperclass && child.widget == newWidget) {
if (child.slot != newSlot) {
updateSlotForChild(child, newSlot);
}
newChild = child;
} else if (hasSameSuperclass && Widget.canUpdate(child.widget, newWidget)) {
if (child.slot != newSlot) {
updateSlotForChild(child, newSlot);
}
child.update(newWidget);
newChild = child;
} else {
deactivateChild(child);
newChild = inflateWidget(newWidget, newSlot);
}
} else {
newChild = inflateWidget(newWidget, newSlot);
}
return newChild;
}
dart
Element? updateChild(Element? child, Widget? newWidget, Object? newSlot) {
if (newWidget == null) {
if (child != null) {
deactivateChild(child);
}
return null;
}
final Element newChild;
if (child != null) {
bool hasSameSuperclass = true;
if (hasSameSuperclass && child.widget == newWidget) {
if (child.slot != newSlot) {
updateSlotForChild(child, newSlot);
}
newChild = child;
} else if (hasSameSuperclass && Widget.canUpdate(child.widget, newWidget)) {
if (child.slot != newSlot) {
updateSlotForChild(child, newSlot);
}
child.update(newWidget);
newChild = child;
} else {
deactivateChild(child);
newChild = inflateWidget(newWidget, newSlot);
}
} else {
newChild = inflateWidget(newWidget, newSlot);
}
return newChild;
}
dart
Element? updateChild(Element? child, Widget? newWidget, Object? newSlot) {
if (newWidget == null) {
if (child != null) {
deactivateChild(child);
}
return null;
}
final Element newChild;
if (child != null) {
bool hasSameSuperclass = true;
if (hasSameSuperclass && child.widget == newWidget) {
if (child.slot != newSlot) {
updateSlotForChild(child, newSlot);
}
newChild = child;
} else if (hasSameSuperclass && Widget.canUpdate(child.widget, newWidget)) {
if (child.slot != newSlot) {
updateSlotForChild(child, newSlot);
}
child.update(newWidget);
newChild = child;
} else {
deactivateChild(child);
newChild = inflateWidget(newWidget, newSlot);
}
} else {
newChild = inflateWidget(newWidget, newSlot);
}
return newChild;
}
update()
element 更新自己。
dart
@mustCallSuper
void update(covariant Widget newWidget) {
_widget = newWidget;
}
dart
@override
void update(StatelessWidget newWidget) {
super.update(newWidget);
rebuild(force: true);
}
dart
@override
void update(StatefulWidget newWidget) {
super.update(newWidget);
final StatefulWidget oldWidget = state._widget!;
state._widget = widget as StatefulWidget; // widget是当前Element持有的_widget_,在调用super.update(newWidget)时,已经把newWidget赋值给_widget
final Object? debugCheckForReturnedFuture = state.didUpdateWidget(oldWidget) as dynamic;
rebuild(force: true);
}
dart
@override
void update(ProxyWidget newWidget) {
final ProxyWidget oldWidget = widget as ProxyWidget;
assert(widget != newWidget);
super.update(newWidget);
assert(widget == newWidget);
updated(oldWidget);
rebuild(force: true);
}
dart
@override
void update(covariant RenderObjectWidget newWidget) {
super.update(newWidget);
assert(widget == newWidget);
_performRebuild(); // calls widget.updateRenderObject()
}
dart
@override
void update(SingleChildRenderObjectWidget newWidget) {
super.update(newWidget);
_child = updateChild(_child, (widget as SingleChildRenderObjectWidget).child, null);
}
dart
@override
void update(MultiChildRenderObjectWidget newWidget) {
super.update(newWidget);
final MultiChildRenderObjectWidget multiChildRenderObjectWidget =
widget as MultiChildRenderObjectWidget;
_children = updateChildren(
_children,
multiChildRenderObjectWidget.children,
forgottenChildren: _forgottenChildren,
);
_forgottenChildren.clear();
}