performLayout method

  1. @override
Size performLayout(
  1. BoxConstraints constraints
)
override

Hook for subclasses to perform layout within the given constraints.

Implementation

@override
Size performLayout(BoxConstraints constraints) {
  final column = widget as Column;
  final width = constraints.maxWidth == BoxConstraints.infinity
      ? 0
      : constraints.maxWidth;
  final height = constraints.maxHeight == BoxConstraints.infinity
      ? 0
      : constraints.maxHeight;
  final area = Rect(0, 0, width, height);

  // Map directly over childElements to retrieve their widgets and calculate
  // constraints, avoiding index desyncs or out-of-bounds errors that could occur
  // if we relied on zip-indexing between column.children and childElements.
  final columnConstraints = childElements
      .map(
        (el) => getConstraint(
          el.widget,
          LayoutDirection.vertical,
          crossSize: width,
          element: el,
        ),
      )
      .toList();
  final rects = splitRect(
    area,
    columnConstraints,
    LayoutDirection.vertical,
    mainAxisAlignment: column.mainAxisAlignment,
  );

  var totalHeight = 0;
  var minChildY = 0;
  var maxChildY = 0;

  for (var i = 0; i < childElements.length; i++) {
    final childEl = childElements[i];
    final childArea = rects[i];
    final minW = column.crossAxisAlignment == CrossAxisAlignment.stretch
        ? width
        : 0;
    final childSize = childEl.layout(
      BoxConstraints(
        minWidth: minW,
        maxWidth: width,
        minHeight: childArea.height,
        maxHeight: childArea.height,
      ),
    );
    childEl.relativeOffset = Offset(childArea.x, childArea.y);
    totalHeight += childSize.height;

    if (childArea.y < minChildY) minChildY = childArea.y;
    if (childArea.y + childSize.height > maxChildY) {
      maxChildY = childArea.y + childSize.height;
    }
  }

  final resolvedHeight = max(
    totalHeight,
    maxChildY,
  ).clamp(constraints.minHeight, constraints.maxHeight);
  _overflowAmount = totalHeight - resolvedHeight;
  _overflowTop = minChildY < 0 ? -minChildY : 0;
  _overflowBottom = maxChildY > resolvedHeight
      ? maxChildY - resolvedHeight
      : 0;

  // Fallback if elements aren't technically out of bounds but totalHeight exceeds
  if (_overflowAmount > 0 && _overflowTop == 0 && _overflowBottom == 0) {
    _overflowBottom = _overflowAmount;
  }

  if (_overflowAmount > 0) {
    logError('Layout Overflow: Column overflowed by $_overflowAmount lines.');
  }

  return Size(width, resolvedHeight);
}