flushLayout method

void flushLayout()

Update the layout information for all dirty render objects.

This function is one of the core stages of the rendering pipeline. Layout information is cleaned prior to painting so that render objects will appear on screen in their up-to-date locations.

See RendererBinding for an example of how this function is used.

Implementation

void flushLayout() {
  if (!kReleaseMode) {
    Map<String, String>? debugTimelineArguments;
    assert(() {
      if (debugEnhanceLayoutTimelineArguments) {
        debugTimelineArguments = <String, String>{
          'dirty count': '${_nodesNeedingLayout.length}',
          'dirty list': '$_nodesNeedingLayout',
        };
      }
      return true;
    }());
    FlutterTimeline.startSync(
      'LAYOUT$_debugRootSuffixForTimelineEventNames',
      arguments: debugTimelineArguments,
    );
  }
  assert(() {
    _debugDoingLayout = true;
    return true;
  }());
  try {
    while (_nodesNeedingLayout.isNotEmpty) {
      assert(!_shouldMergeDirtyNodes);
      final List<RenderObject> dirtyNodes = _nodesNeedingLayout;
      _nodesNeedingLayout = <RenderObject>[];
      dirtyNodes.sort((RenderObject a, RenderObject b) => a.depth - b.depth);
      for (int i = 0; i < dirtyNodes.length; i++) {
        if (_shouldMergeDirtyNodes) {
          _shouldMergeDirtyNodes = false;
          if (_nodesNeedingLayout.isNotEmpty) {
            _nodesNeedingLayout.addAll(dirtyNodes.getRange(i, dirtyNodes.length));
            break;
          }
        }
        final RenderObject node = dirtyNodes[i];
        if (node._needsLayout && node.owner == this) {
          node._layoutWithoutResize();
        }
      }
      // No need to merge dirty nodes generated from processing the last
      // relayout boundary back.
      _shouldMergeDirtyNodes = false;
    }

    assert(() {
      _debugDoingChildLayout = true;
      return true;
    }());
    for (final PipelineOwner child in _children) {
      child.flushLayout();
    }
    assert(_nodesNeedingLayout.isEmpty, 'Child PipelineOwners must not dirty nodes in their parent.');
  } finally {
    _shouldMergeDirtyNodes = false;
    assert(() {
      _debugDoingLayout = false;
      _debugDoingChildLayout = false;
      return true;
    }());
    if (!kReleaseMode) {
      FlutterTimeline.finishSync();
    }
  }
}