Unverified Commit 152f5258 authored by xster's avatar xster Committed by GitHub

Let RenderSliverFixedExtentBoxAdapter handle disappearing top items (#12919)

* fix with first part of test

* Test without reshifting

* Let sliver fixed extend list also handle disappearing top items.
parent 97b3742f
......@@ -148,6 +148,13 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
for (int index = indexOf(firstChild) - 1; index >= firstIndex; --index) {
final RenderBox child = insertAndLayoutLeadingChild(childConstraints);
if (child == null) {
// Items before the previously first child are no longer present.
// Reset the scroll offset to offset all items prior and up to the
// missing item. Let parent re-layout everything.
geometry = new SliverGeometry(scrollOffsetCorrection: index * itemExtent);
return;
}
final SliverMultiBoxAdaptorParentData childParentData = child.parentData;
childParentData.layoutOffset = indexToLayoutOffset(itemExtent, index);
assert(childParentData.index == index);
......
......@@ -194,4 +194,67 @@ void main() {
await tester.pumpAndSettle(const Duration(milliseconds: 122));
});
testWidgets('Removing offscreen items above and rescrolling does not crash', (WidgetTester tester) async {
await tester.pumpWidget(new MaterialApp(
home: new CustomScrollView(
slivers: <Widget>[
new SliverFixedExtentList(
itemExtent: 100.0,
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
return new Container(
color: Colors.blue,
child: new Text(index.toString()),
);
},
childCount: 30,
),
),
],
),
));
await tester.drag(find.text('5'), const Offset(0.0, -500.0));
await tester.pump();
// Screen is 600px high. Moved bottom item 500px up. It's now at the top.
expect(tester.getTopLeft(find.widgetWithText(DecoratedBox, '5')).dy, 0.0);
expect(tester.getBottomLeft(find.widgetWithText(DecoratedBox, '10')).dy, 600.0);
// Stop returning the first 3 items.
await tester.pumpWidget(new MaterialApp(
home: new CustomScrollView(
slivers: <Widget>[
new SliverFixedExtentList(
itemExtent: 100.0,
delegate: new SliverChildBuilderDelegate(
(BuildContext context, int index) {
if (index > 3) {
return new Container(
color: Colors.blue,
child: new Text(index.toString()),
);
}
return null;
},
childCount: 30,
),
),
],
),
));
await tester.drag(find.text('5'), const Offset(0.0, 400.0));
await tester.pump();
// Move up by 4 items, meaning item 1 would have been at the top but
// 0 through 3 no longer exist, so item 4, 3 items down, is the first one.
// Item 4 is also shifted to the top.
expect(tester.getTopLeft(find.widgetWithText(DecoratedBox, '4')).dy, 0.0);
// Because the screen is still 600px, item 9 is now visible at the bottom instead
// of what's supposed to be item 6 had we not re-shifted.
expect(tester.getBottomLeft(find.widgetWithText(DecoratedBox, '9')).dy, 600.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