Unverified Commit 9d942792 authored by Kate Lovett's avatar Kate Lovett Committed by GitHub

Fix extent for null returning builder in GridView (#132511)

Fixes https://github.com/flutter/flutter/issues/130685

This fixes an issue where a GridView/SliverGrid with a SliverChildBuilderDelegate would still reflect a max scroll extent of infinity after returning null from the builder. This change incorporates the same way we handle this case in SliverList:

https://github.com/flutter/flutter/blob/6d87a23b3722e4fb2e2db993322d5be4adf04fb5/packages/flutter/lib/src/rendering/sliver_list.dart#L305-L307
parent 899a29f8
......@@ -631,6 +631,7 @@ class RenderSliverGrid extends RenderSliverMultiBoxAdaptor {
final double leadingScrollOffset = firstChildGridGeometry.scrollOffset;
double trailingScrollOffset = firstChildGridGeometry.trailingScrollOffset;
RenderBox? trailingChildWithLayout;
bool reachedEnd = false;
for (int index = indexOf(firstChild!) - 1; index >= firstIndex; --index) {
final SliverGridGeometry gridGeometry = layout.getGeometryForChildIndex(index);
......@@ -660,6 +661,7 @@ class RenderSliverGrid extends RenderSliverMultiBoxAdaptor {
if (child == null || indexOf(child) != index) {
child = insertAndLayoutChild(childConstraints, after: trailingChildWithLayout);
if (child == null) {
reachedEnd = true;
// We have run out of children.
break;
}
......@@ -680,13 +682,15 @@ class RenderSliverGrid extends RenderSliverMultiBoxAdaptor {
assert(indexOf(firstChild!) == firstIndex);
assert(targetLastIndex == null || lastIndex <= targetLastIndex);
final double estimatedTotalExtent = childManager.estimateMaxScrollOffset(
constraints,
firstIndex: firstIndex,
lastIndex: lastIndex,
leadingScrollOffset: leadingScrollOffset,
trailingScrollOffset: trailingScrollOffset,
);
final double estimatedTotalExtent = reachedEnd
? trailingScrollOffset
: childManager.estimateMaxScrollOffset(
constraints,
firstIndex: firstIndex,
lastIndex: lastIndex,
leadingScrollOffset: leadingScrollOffset,
trailingScrollOffset: trailingScrollOffset,
);
final double paintExtent = calculatePaintOffset(
constraints,
from: math.min(constraints.scrollOffset, leadingScrollOffset),
......
......@@ -856,6 +856,43 @@ void main() {
maxCrossAxisExtent: maxCrossAxisExtent,
),
), throwsAssertionError);
});
testWidgets('SliverGrid sets correct extent for null returning builder delegate', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/130685
final ScrollController controller = ScrollController();
await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr,
child: GridView.builder(
controller: controller,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 16,
mainAxisSpacing: 16,
),
itemBuilder: (BuildContext context, int index) {
if (index == 12) {
return null;
}
return Container(
height: 100,
width: 100,
color: const Color(0xFFFF8A80),
alignment: Alignment.center,
child: Text('item ${index+1}'),
);
},
),
));
await tester.pumpAndSettle();
expect(controller.position.maxScrollExtent, double.infinity);
expect(controller.position.pixels, 0.0);
await tester.fling(find.byType(GridView), const Offset(0.0, -1300.0), 100.0);
await tester.pumpAndSettle();
// The actual extent of the children is 472.0. This should be reflected when
// the builder returns null (meaning we have reached the end).
expect(controller.position.maxScrollExtent, 472.0);
expect(controller.position.pixels, 472.0);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment