fixed 33347 fill the gap during performLayout in SliverGrid and SliverFixedExtentList (#33467)
This commit is contained in:
parent
6feedcc6a4
commit
bfc6df0e4f
@ -211,9 +211,9 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
|
||||
trailingChildWithLayout = firstChild;
|
||||
}
|
||||
|
||||
while (targetLastIndex == null || indexOf(trailingChildWithLayout) < targetLastIndex) {
|
||||
for (int index = indexOf(trailingChildWithLayout) + 1; targetLastIndex == null || index <= targetLastIndex; ++index) {
|
||||
RenderBox child = childAfter(trailingChildWithLayout);
|
||||
if (child == null) {
|
||||
if (child == null || indexOf(child) != index) {
|
||||
child = insertAndLayoutChild(childConstraints, after: trailingChildWithLayout);
|
||||
if (child == null) {
|
||||
// We have run out of children.
|
||||
@ -225,6 +225,7 @@ abstract class RenderSliverFixedExtentBoxAdaptor extends RenderSliverMultiBoxAda
|
||||
trailingChildWithLayout = child;
|
||||
assert(child != null);
|
||||
final SliverMultiBoxAdaptorParentData childParentData = child.parentData;
|
||||
assert(childParentData.index == index);
|
||||
childParentData.layoutOffset = indexToLayoutOffset(itemExtent, childParentData.index);
|
||||
}
|
||||
|
||||
|
@ -579,7 +579,7 @@ class RenderSliverGrid extends RenderSliverMultiBoxAdaptor {
|
||||
final SliverGridGeometry gridGeometry = layout.getGeometryForChildIndex(index);
|
||||
final BoxConstraints childConstraints = gridGeometry.getBoxConstraints(constraints);
|
||||
RenderBox child = childAfter(trailingChildWithLayout);
|
||||
if (child == null) {
|
||||
if (child == null || indexOf(child) != index) {
|
||||
child = insertAndLayoutChild(childConstraints, after: trailingChildWithLayout);
|
||||
if (child == null) {
|
||||
// We have run out of children.
|
||||
|
@ -196,6 +196,73 @@ void main() {
|
||||
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 {
|
||||
const Text errorText = Text('error');
|
||||
final ErrorWidgetBuilder oldBuilder = ErrorWidget.builder;
|
||||
@ -212,3 +279,56 @@ void main() {
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user