开始
从Element.updateChild开始.这里先不看创建等其他过程.
Element updateChild(Element child, Widget newWidget, dynamic newSlot) {
...
child.update(newWidget);
newChild = child;
...
return newChild;
}
RenderObjectElement.update
RenderObjectElement它有一个自己实现的update,它这里就是调用了RenderObjectWidget的updateRenderObject方法.
@override
void update(covariant RenderObjectWidget newWidget) {
super.update(newWidget);
widget.updateRenderObject(this, renderObject);
_dirty = false;
}
其实RenderObejctElement的子类还有自己实现的update方法,但是一般都是继续更新子组件,所以这里暂不多说.
Padding.updateRenderObject
看源码我们可以发现RenderObjectWidget的updateRenderObject是一个空方法,这里我们直接看子类的实现,我们这里以Padding举例.
@override
void updateRenderObject(BuildContext context, RenderPadding renderObject) {
renderObject
///这里会调用RenderPadding的padding set方法.
..padding = padding
..textDirection = Directionality.of(context);
}
RenderPadding.padding
///RenderPadding.padding
set padding(EdgeInsetsGeometry value) {
///这里它做了一个优化,如果,更新的padding和当前的padding相同则不更新.
if (_padding == value)
return;
_padding = value;
///这里会标记需要更新.
_markNeedResolution();
}
RenderPadding._markNeedResolution
void _markNeedResolution() {
_resolvedPadding = null;
///这里标记当前这个renderObject是需要重新layout的.
markNeedsLayout();
}
RenderObject.markNeedsLayout
void markNeedsLayout() {
///如果已标记为需要更新则退出.
if (_needsLayout) {
return;
}
///如果当前renderObject并不是_relayoutBoundary则调用父组件的markNeedsLayout
///递归到满足条件为止
if (_relayoutBoundary != this) {
markParentNeedsLayout();
} else {
_needsLayout = true;
if (owner != null) {
///将当前RenderObject添加到需要重新 layout的数组中
owner._nodesNeedingLayout.add(this);
owner.requestVisualUpdate();
}
}
}
PipelineOwner.flushLayout
void flushLayout() {
if (!kReleaseMode) {
Timeline.startSync('Layout', arguments: timelineArgumentsIndicatingLandmarkEvent);
}
try {
while (_nodesNeedingLayout.isNotEmpty) {
final List<RenderObject> dirtyNodes = _nodesNeedingLayout;
_nodesNeedingLayout = <RenderObject>[];
for (final RenderObject node in dirtyNodes..sort((RenderObject a, RenderObject b) => a.depth - b.depth)) {
if (node._needsLayout && node.owner == this)
node._layoutWithoutResize();
}
}
} finally {
if (!kReleaseMode) {
Timeline.finishSync();
}
}
}
RenderObject._layoutWithoutResize
void _layoutWithoutResize() {
RenderObject debugPreviousActiveLayout;
try {
/// 这里的performLayout方法RenderObject和RenderBox都没有实现,我们这里看一下RenderPadding实现的方法.
performLayout();
markNeedsSemanticsUpdate();
} catch (e, stack) {
_debugReportException('performLayout', e, stack);
}
_needsLayout = false;
/// 这里会在performLayout之后调用
markNeedsPaint();
}
RenderPadding.performLayout
@override
void performLayout() {
final BoxConstraints constraints = this.constraints;
_resolve();
if (child == null) {
size = constraints.constrain(Size(
_resolvedPadding.left + _resolvedPadding.right,
_resolvedPadding.top + _resolvedPadding.bottom,
));
return;
}
final BoxConstraints innerConstraints = constraints.deflate(_resolvedPadding);
///给子节点的大小约束.
child.layout(innerConstraints, parentUsesSize: true);
final BoxParentData childParentData = child.parentData as BoxParentData;
///控制子组件在父组件的位置.
childParentData.offset = Offset(_resolvedPadding.left, _resolvedPadding.top);
///当前widget的size大小,这里的size就是Padding的size
size = constraints.constrain(Size(
_resolvedPadding.left + child.size.width + _resolvedPadding.right,
_resolvedPadding.top + child.size.height + _resolvedPadding.bottom,
));
}
RenderObject.markNeedsPaint
void markNeedsPaint() {
if (_needsPaint)
return;
///标记需要重新paint
_needsPaint = true;
///如果RenderObject.isRepaintBoundary为true,则该RenderObject拥有layer,直接绘制
if (isRepaintBoundary) {
if (owner != null) {
///找到最近的layer,绘制
owner._nodesNeedingPaint.add(this);
owner.requestVisualUpdate();
}
} else if (parent is RenderObject) {
///没有自己的layer,会和祖先节点共用一个layer
final RenderObject parent = this.parent as RenderObject;
///向父级递归查找.
parent.markNeedsPaint();
} else {
if (owner != null)
owner.requestVisualUpdate();
}
}
PipelineOwner.flushPaint
void flushPaint() {
if (!kReleaseMode) {
Timeline.startSync('Paint', arguments: timelineArgumentsIndicatingLandmarkEvent);
}
try {
final List<RenderObject> dirtyNodes = _nodesNeedingPaint;
_nodesNeedingPaint = <RenderObject>[];
// Sort the dirty nodes in reverse order (deepest first).
for (final RenderObject node in dirtyNodes..sort((RenderObject a, RenderObject b) => b.depth - a.depth)) {
if (node._needsPaint && node.owner == this) {
if (node._layer.attached) {
///真正的绘制逻辑
PaintingContext.repaintCompositedChild(node);
} else {
node._skippedPaintingOnLayer();
}
}
}
} finally {
if (!kReleaseMode) {
Timeline.finishSync();
}
}
}
到这里就差不过更新结束了.