performLayout method
Do the work of computing the layout for this render object.
Do not call this function directly: call layout instead. This function is called by layout when there is actually work to be done by this render object during layout. The layout constraints provided by your parent are available via the constraints getter.
If sizedByParent is true, then this function should not actually change the dimensions of this render object. Instead, that work should be done by performResize. If sizedByParent is false, then this function should both change the dimensions of this render object and instruct its children to layout.
In implementing this function, you must call layout on each of your children, passing true for parentUsesSize if your layout information is dependent on your child's layout information. Passing true for parentUsesSize ensures that this render object will undergo layout if the child undergoes layout. Otherwise, the child can change its layout information without informing this render object.
Implementation
@override
void performLayout() {
final SliverConstraints constraints = this.constraints;
// The remaining space in the viewportMainAxisExtent. Can be <= 0 if we have
// scrolled beyond the extent of the screen.
double extent = constraints.viewportMainAxisExtent - constraints.precedingScrollExtent;
// The maxExtent includes any overscrolled area. Can be < 0 if we have
// overscroll in the opposite direction, away from the end of the list.
double maxExtent = constraints.remainingPaintExtent - math.min(constraints.overlap, 0.0);
if (child != null) {
final double childExtent = switch (constraints.axis) {
Axis.horizontal => child!.getMaxIntrinsicWidth(constraints.crossAxisExtent),
Axis.vertical => child!.getMaxIntrinsicHeight(constraints.crossAxisExtent),
};
// If the childExtent is greater than the computed extent, we want to use
// that instead of potentially cutting off the child. This allows us to
// safely specify a maxExtent.
extent = math.max(extent, childExtent);
// The extent could be larger than the maxExtent due to a larger child
// size or overscrolling at the top of the scrollable (rather than at the
// end where this sliver is).
maxExtent = math.max(extent, maxExtent);
child!.layout(constraints.asBoxConstraints(minExtent: extent, maxExtent: maxExtent));
}
assert(extent.isFinite,
'The calculated extent for the child of SliverFillRemaining is not finite. '
'This can happen if the child is a scrollable, in which case, the '
'hasScrollBody property of SliverFillRemaining should not be set to '
'false.',
);
final double paintedChildSize = calculatePaintOffset(constraints, from: 0.0, to: extent);
assert(paintedChildSize.isFinite);
assert(paintedChildSize >= 0.0);
final double cacheExtent = calculateCacheOffset(constraints, from: 0.0, to: extent);
geometry = SliverGeometry(
scrollExtent: extent,
paintExtent: math.min(maxExtent, constraints.remainingPaintExtent),
maxPaintExtent: maxExtent,
hasVisualOverflow: extent > constraints.remainingPaintExtent || constraints.scrollOffset > 0.0,
cacheExtent: cacheExtent,
);
if (child != null) {
setChildParentData(child!, constraints, geometry!);
}
}