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 row = widget as Row;
  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 row.children and childElements.
  final rowConstraints = childElements
      .map(
        (el) => getConstraint(
          el.widget,
          LayoutDirection.horizontal,
          crossSize: height,
          element: el,
        ),
      )
      .toList();
  final rects = splitRect(
    area,
    rowConstraints,
    LayoutDirection.horizontal,
    mainAxisAlignment: row.mainAxisAlignment,
  );

  var maxChildHeight = 0;
  var totalWidth = 0;

  var minChildX = 0;
  var maxChildX = 0;

  for (var i = 0; i < childElements.length; i++) {
    final childEl = childElements[i];
    final childArea = rects[i];
    final minH = row.crossAxisAlignment == CrossAxisAlignment.stretch
        ? height
        : 0;
    final childSize = childEl.layout(
      BoxConstraints(
        minWidth: childArea.width,
        maxWidth: childArea.width,
        minHeight: minH,
        maxHeight: height,
      ),
    );
    childEl.relativeOffset = Offset(childArea.x, childArea.y);
    if (childSize.height > maxChildHeight) {
      maxChildHeight = childSize.height;
    }
    totalWidth += childSize.width;

    if (childArea.x < minChildX) minChildX = childArea.x;
    if (childArea.x + childSize.width > maxChildX) {
      maxChildX = childArea.x + childSize.width;
    }
  }

  final resolvedWidth = max(
    totalWidth,
    maxChildX,
  ).clamp(constraints.minWidth, constraints.maxWidth);
  _overflowAmount = totalWidth - resolvedWidth;
  _overflowLeft = minChildX < 0 ? -minChildX : 0;
  _overflowRight = maxChildX > resolvedWidth ? maxChildX - resolvedWidth : 0;

  // Fallback if elements aren't technically out of bounds but totalWidth exceeds
  if (_overflowAmount > 0 && _overflowLeft == 0 && _overflowRight == 0) {
    _overflowRight = _overflowAmount;
  }

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

  return Size(resolvedWidth, maxChildHeight);
}