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:
6d87a23b37/packages/flutter/lib/src/rendering/sliver_list.dart (L305-L307)
This commit is contained in:
parent
899a29f830
commit
9d9427923f
@ -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);
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user