markNeedsLayout method

  1. @override
void markNeedsLayout()
override

Mark this render object's layout information as dirty, and either register this object with its PipelineOwner, or defer to the parent, depending on whether this object is a relayout boundary or not respectively.

Background

Rather than eagerly updating layout information in response to writes into a render object, we instead mark the layout information as dirty, which schedules a visual update. As part of the visual update, the rendering pipeline updates the render object's layout information.

This mechanism batches the layout work so that multiple sequential writes are coalesced, removing redundant computation.

If a render object's parent indicates that it uses the size of one of its render object children when computing its layout information, this function, when called for the child, will also mark the parent as needing layout. In that case, since both the parent and the child need to have their layout recomputed, the pipeline owner is only notified about the parent; when the parent is laid out, it will call the child's layout method and thus the child will be laid out as well.

Once markNeedsLayout has been called on a render object, debugNeedsLayout returns true for that render object until just after the pipeline owner has called layout on the render object.

Special cases

Some subclasses of RenderObject, notably RenderBox, have other situations in which the parent needs to be notified if the child is dirtied (e.g., if the child's intrinsic dimensions or baseline changes). Such subclasses override markNeedsLayout and either call super.markNeedsLayout(), in the normal case, or call markParentNeedsLayout, in the case where the parent needs to be laid out as well as the child.

If sizedByParent has changed, calls markNeedsLayoutForSizedByParentChange instead of markNeedsLayout.

Implementation

@override
void markNeedsLayout() {
  // If `_layoutCacheStorage.clear` returns true, then this [RenderBox]'s layout
  // is used by the parent's layout algorithm (it's possible that the parent
  // only used the intrinsics for paint, but there's no good way to detect that
  // so we conservatively assume it's a layout dependency).
  //
  // A render object's performLayout implementation may depend on the baseline
  // location or the intrinsic dimensions of a descendant, even when there are
  // relayout boundaries between them. The `_layoutCacheStorage` being non-empty
  // indicates that the parent depended on this RenderBox's baseline location,
  // or intrinsic sizes, and thus may need relayout, regardless of relayout
  // boundaries.
  //
  // Some calculations may fail (dry baseline, for example). The layout
  // dependency is still established, but only from the RenderBox that failed
  // to compute the dry baseline to the ancestor that queried the dry baseline.
  if (_layoutCacheStorage.clear() && parent != null) {
    markParentNeedsLayout();
    return;
  }
  super.markNeedsLayout();
}