diff --git a/packages/flutter/lib/src/rendering/sliver_group.dart b/packages/flutter/lib/src/rendering/sliver_group.dart index cc181494632..f10415f1b60 100644 --- a/packages/flutter/lib/src/rendering/sliver_group.dart +++ b/packages/flutter/lib/src/rendering/sliver_group.dart @@ -263,7 +263,14 @@ class RenderSliverMainAxisGroup extends RenderSliver double maxPaintExtent = 0; double paintOffset = constraints.overlap; - RenderSliver? child = firstChild; + final ( + RenderSliver? leadingChild, + RenderSliver? Function(RenderSliver child) advance, + ) = switch (constraints.growthDirection) { + GrowthDirection.forward => (firstChild, childAfter), + GrowthDirection.reverse => (lastChild, childBefore), + }; + RenderSliver? child = leadingChild; while (child != null) { final double beforeOffsetPaintExtent = calculatePaintOffset( constraints, @@ -298,7 +305,7 @@ class RenderSliverMainAxisGroup extends RenderSliver layoutOffset += childLayoutGeometry.layoutExtent; maxPaintExtent += childLayoutGeometry.maxPaintExtent; paintOffset = math.max(childPaintOffset + childLayoutGeometry.paintExtent, paintOffset); - child = childAfter(child); + child = advance(child); assert(() { if (child != null && maxPaintExtent.isInfinite) { throw FlutterError( @@ -349,11 +356,14 @@ class RenderSliverMainAxisGroup extends RenderSliver // Update the children's paintOffset based on the direction again, which // must be done after obtaining the `paintExtent`. - child = firstChild; + child = leadingChild; while (child != null) { final SliverPhysicalParentData childParentData = child.parentData! as SliverPhysicalParentData; - childParentData.paintOffset = switch (constraints.axisDirection) { + childParentData.paintOffset = switch (applyGrowthDirectionToAxisDirection( + constraints.axisDirection, + constraints.growthDirection, + )) { AxisDirection.up => Offset( 0.0, paintExtent - childParentData.paintOffset.dy - child.geometry!.paintExtent, @@ -364,7 +374,7 @@ class RenderSliverMainAxisGroup extends RenderSliver ), AxisDirection.right || AxisDirection.down => childParentData.paintOffset, }; - child = childAfter(child); + child = advance(child); } } diff --git a/packages/flutter/test/widgets/sliver_main_axis_group_test.dart b/packages/flutter/test/widgets/sliver_main_axis_group_test.dart index e475e47a2a2..2910c130c10 100644 --- a/packages/flutter/test/widgets/sliver_main_axis_group_test.dart +++ b/packages/flutter/test/widgets/sliver_main_axis_group_test.dart @@ -1062,6 +1062,41 @@ void main() { await tester.pumpAndSettle(); expect(tester.takeException(), isNull); }); + + testWidgets('SliverMainAxisGroup with center', (WidgetTester tester) async { + final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); + const Key centerKey = Key('center'); + await tester.pumpWidget( + MaterialApp( + home: CustomScrollView( + center: centerKey, + controller: controller, + slivers: const [ + SliverMainAxisGroup( + slivers: [ + SliverToBoxAdapter(child: SizedBox(height: 50, child: Text('-2'))), + SliverToBoxAdapter(child: SizedBox(height: 50, child: Text('-1'))), + ], + ), + SliverMainAxisGroup( + key: centerKey, + slivers: [ + SliverToBoxAdapter(child: SizedBox(height: 50, child: Text('1'))), + SliverToBoxAdapter(child: SizedBox(height: 50, child: Text('2'))), + ], + ), + ], + ), + ), + ); + controller.jumpTo(-51); + await tester.pumpAndSettle(); + expect(tester.getTopLeft(find.text('-1')), const Offset(0, 1)); + expect(tester.getTopLeft(find.text('1')), const Offset(0, 51)); + expect(tester.getTopLeft(find.text('2')), const Offset(0, 101)); + expect(tester.getTopLeft(find.text('-2')), const Offset(0, -49)); + }); } Widget _buildSliverList({