performBoxLayout method
Perform layout with typed box constraints
Subclasses override this instead of performLayout. The default implementation sizes to the maxima, treating an unbounded axis as the corresponding lower bound.
Implementation
@override
void performBoxLayout(BoxConstraints constraints) {
final boxes = children.whereType<RenderBox>().toList(growable: false);
var naturalWidth = 0;
var naturalHeight = 0;
var hasNonPositionedChild = false;
final loose = BoxConstraints.loose(
maxWidth: constraints.maxWidth,
maxHeight: constraints.maxHeight,
);
for (final child in boxes) {
final data = _childData[child] ?? const StackChildData();
if (data.isPositioned) continue;
hasNonPositionedChild = true;
final childConstraints = _fit == StackFit.expand
? BoxConstraints.expand(
width: constraints.maxWidth,
height: constraints.maxHeight,
)
: loose;
child.layout(childConstraints);
if (child.size.width > naturalWidth) naturalWidth = child.size.width;
if (child.size.height > naturalHeight) naturalHeight = child.size.height;
}
if (!hasNonPositionedChild &&
(constraints.maxWidth == null || constraints.maxHeight == null)) {
for (final child in boxes) {
final data = _childData[child] ?? const StackChildData();
child.layout(
_positionedConstraints(
data,
width: constraints.maxWidth,
height: constraints.maxHeight,
),
);
naturalWidth = math.max(
naturalWidth,
_positionedExtent(child.size.width, data.left, data.right),
);
naturalHeight = math.max(
naturalHeight,
_positionedExtent(child.size.height, data.top, data.bottom),
);
}
}
final fillAvailable = _fit == StackFit.expand || !hasNonPositionedChild;
size = Size(
constraints.constrainWidth(
fillAvailable ? constraints.maxWidth ?? naturalWidth : naturalWidth,
),
constraints.constrainHeight(
fillAvailable ? constraints.maxHeight ?? naturalHeight : naturalHeight,
),
);
for (final child in boxes) {
final data = _childData[child] ?? const StackChildData();
if (!data.isPositioned) {
final offset = _alignedOffset(
_alignment,
Offset(
size.width - child.size.width,
size.height - child.size.height,
),
);
positionChild(child, offset.dx, offset.dy);
continue;
}
child.layout(
_positionedConstraints(data, width: size.width, height: size.height),
);
final aligned = _alignedOffset(
_alignment,
Offset(size.width - child.size.width, size.height - child.size.height),
);
final x =
data.left ??
(data.right == null
? aligned.dx
: size.width - data.right! - child.size.width);
final y =
data.top ??
(data.bottom == null
? aligned.dy
: size.height - data.bottom! - child.size.height);
positionChild(child, x, y);
}
}