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

diff --git a/packages/flutter/lib/src/rendering/sliver_fixed_extent_list.dart b/packages/flutter/lib/src/rendering/sliver_fixed_extent_list.dart
index 0c5dc4b..221897f 100644
--- a/packages/flutter/lib/src/rendering/sliver_fixed_extent_list.dart
+++ b/packages/flutter/lib/src/rendering/sliver_fixed_extent_list.dart
@@ -211,9 +211,9 @@
       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 @@
       trailingChildWithLayout = child;
       assert(child != null);
       final SliverMultiBoxAdaptorParentData childParentData = child.parentData;
+      assert(childParentData.index == index);
       childParentData.layoutOffset = indexToLayoutOffset(itemExtent, childParentData.index);
     }
 
diff --git a/packages/flutter/lib/src/rendering/sliver_grid.dart b/packages/flutter/lib/src/rendering/sliver_grid.dart
index 3d23d56..f5901ef 100644
--- a/packages/flutter/lib/src/rendering/sliver_grid.dart
+++ b/packages/flutter/lib/src/rendering/sliver_grid.dart
@@ -579,7 +579,7 @@
       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.
diff --git a/packages/flutter/test/widgets/slivers_test.dart b/packages/flutter/test/widgets/slivers_test.dart
index ed5e213..e2c4c93 100644
--- a/packages/flutter/test/widgets/slivers_test.dart
+++ b/packages/flutter/test/widgets/slivers_test.dart
@@ -196,6 +196,73 @@
     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 @@
     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,
+              ),
+            ),
+          ],
+        )
+    );
+  }
+}