Unverified Commit bfc6df0e authored by chunhtai's avatar chunhtai Committed by GitHub

fixed 33347 fill the gap during performLayout in SliverGrid and SliverFixedExtentList (#33467)

parent 6feedcc6
...@@ -211,9 +211,9 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda ...@@ -211,9 +211,9 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
trailingChildWithLayout = firstChild; trailingChildWithLayout = firstChild;
} }
while (targetLastIndex == null || indexOf(trailingChildWithLayout) < targetLastIndex) { for (int index = indexOf(trailingChildWithLayout) + 1; targetLastIndex == null || index <= targetLastIndex; ++index) {
RenderBox child = childAfter(trailingChildWithLayout); RenderBox child = childAfter(trailingChildWithLayout);
if (child == null) { if (child == null || indexOf(child) != index) {
child = insertAndLayoutChild(childConstraints, after: trailingChildWithLayout); child = insertAndLayoutChild(childConstraints, after: trailingChildWithLayout);
if (child == null) { if (child == null) {
// We have run out of children. // We have run out of children.
...@@ -225,6 +225,7 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda ...@@ -225,6 +225,7 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
trailingChildWithLayout = child; trailingChildWithLayout = child;
assert(child != null); assert(child != null);
final SliverMultiBoxAdaptorParentData childParentData = child.parentData; final SliverMultiBoxAdaptorParentData childParentData = child.parentData;
assert(childParentData.index == index);
childParentData.layoutOffset = indexToLayoutOffset(itemExtent, childParentData.index); childParentData.layoutOffset = indexToLayoutOffset(itemExtent, childParentData.index);
} }
......
...@@ -579,7 +579,7 @@ class RenderSliverGrid extends RenderSliverMultiBoxAdaptor { ...@@ -579,7 +579,7 @@ class RenderSliverGrid extends RenderSliverMultiBoxAdaptor {
final SliverGridGeometry gridGeometry = layout.getGeometryForChildIndex(index); final SliverGridGeometry gridGeometry = layout.getGeometryForChildIndex(index);
final BoxConstraints childConstraints = gridGeometry.getBoxConstraints(constraints); final BoxConstraints childConstraints = gridGeometry.getBoxConstraints(constraints);
RenderBox child = childAfter(trailingChildWithLayout); RenderBox child = childAfter(trailingChildWithLayout);
if (child == null) { if (child == null || indexOf(child) != index) {
child = insertAndLayoutChild(childConstraints, after: trailingChildWithLayout); child = insertAndLayoutChild(childConstraints, after: trailingChildWithLayout);
if (child == null) { if (child == null) {
// We have run out of children. // We have run out of children.
......
...@@ -196,6 +196,73 @@ void main() { ...@@ -196,6 +196,73 @@ void main() {
expect(find.text('BOTTOM'), findsOneWidget); expect(find.text('BOTTOM'), findsOneWidget);
}); });
testWidgets('SliverGrid Correctly layout children after rearranging', (WidgetTester tester) async {
await tester.pumpWidget(const TestSliverGrid(
<Widget>[
Text('item0', key: Key('0')),
Text('item1', key: Key('1')),
]
));
await tester.pumpWidget(const TestSliverGrid(
<Widget>[
Text('item0', key: Key('0')),
Text('item3', key: Key('3')),
Text('item4', key: Key('4')),
Text('item1', key: Key('1')),
]
));
expect(find.text('item0'), findsOneWidget);
expect(find.text('item3'), findsOneWidget);
expect(find.text('item4'), findsOneWidget);
expect(find.text('item1'), findsOneWidget);
final Offset item0Location = tester.getCenter(find.text('item0'));
final Offset item3Location = tester.getCenter(find.text('item3'));
final Offset item4Location = tester.getCenter(find.text('item4'));
final Offset item1Location = tester.getCenter(find.text('item1'));
expect(isRight(item0Location, item3Location) && sameHorizontal(item0Location, item3Location), true);
expect(isBelow(item0Location, item4Location) && sameVertical(item0Location, item4Location), true);
expect(isBelow(item0Location, item1Location) && isRight(item0Location, item1Location), true);
},
);
testWidgets('SliverFixedExtentList Correctly layout children after rearranging', (WidgetTester tester) async {
await tester.pumpWidget(const TestSliverFixedExtentList(
<Widget>[
Text('item0', key: Key('0')),
Text('item2', key: Key('2')),
Text('item1', key: Key('1')),
]
));
await tester.pumpWidget(const TestSliverFixedExtentList(
<Widget>[
Text('item0', key: Key('0')),
Text('item3', key: Key('3')),
Text('item1', key: Key('1')),
Text('item4', key: Key('4')),
Text('item2', key: Key('2')),
]
));
expect(find.text('item0'), findsOneWidget);
expect(find.text('item3'), findsOneWidget);
expect(find.text('item1'), findsOneWidget);
expect(find.text('item4'), findsOneWidget);
expect(find.text('item2'), findsOneWidget);
final Offset item0Location = tester.getCenter(find.text('item0'));
final Offset item3Location = tester.getCenter(find.text('item3'));
final Offset item1Location = tester.getCenter(find.text('item1'));
final Offset item4Location = tester.getCenter(find.text('item4'));
final Offset item2Location = tester.getCenter(find.text('item2'));
expect(isBelow(item0Location, item3Location) && sameVertical(item0Location, item3Location), true);
expect(isBelow(item3Location, item1Location) && sameVertical(item3Location, item1Location), true);
expect(isBelow(item1Location, item4Location) && sameVertical(item1Location, item4Location), true);
expect(isBelow(item4Location, item2Location) && sameVertical(item4Location, item2Location), true);
},
);
testWidgets('Can override ErrorWidget.build', (WidgetTester tester) async { testWidgets('Can override ErrorWidget.build', (WidgetTester tester) async {
const Text errorText = Text('error'); const Text errorText = Text('error');
final ErrorWidgetBuilder oldBuilder = ErrorWidget.builder; final ErrorWidgetBuilder oldBuilder = ErrorWidget.builder;
...@@ -212,3 +279,56 @@ void main() { ...@@ -212,3 +279,56 @@ void main() {
ErrorWidget.builder = oldBuilder; ErrorWidget.builder = oldBuilder;
}); });
} }
bool isRight(Offset a, Offset b) => b.dx > a.dx;
bool isBelow(Offset a, Offset b) => b.dy > a.dy;
bool sameHorizontal(Offset a, Offset b) => b.dy == a.dy;
bool sameVertical(Offset a, Offset b) => b.dx == a.dx;
class TestSliverGrid extends StatelessWidget {
const TestSliverGrid(this.children);
final List<Widget> children;
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.ltr,
child: CustomScrollView(
slivers: <Widget> [
SliverGrid(
delegate: SliverChildListDelegate(
children,
),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
),
],
)
);
}
}
class TestSliverFixedExtentList extends StatelessWidget {
const TestSliverFixedExtentList(this.children);
final List<Widget> children;
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.ltr,
child: CustomScrollView(
slivers: <Widget> [
SliverFixedExtentList(
itemExtent: 10.0,
delegate: SliverChildListDelegate(
children,
),
),
],
)
);
}
}
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