Unverified Commit 144434ca authored by Darren Austin's avatar Darren Austin Committed by GitHub

Fixed an issue with overflow exceptions with nested lists inside a reorderable list item. (#84828)

parent 2e5284a2
...@@ -12,6 +12,7 @@ import 'basic.dart'; ...@@ -12,6 +12,7 @@ import 'basic.dart';
import 'debug.dart'; import 'debug.dart';
import 'framework.dart'; import 'framework.dart';
import 'inherited_theme.dart'; import 'inherited_theme.dart';
import 'media_query.dart';
import 'overlay.dart'; import 'overlay.dart';
import 'scroll_controller.dart'; import 'scroll_controller.dart';
import 'scroll_physics.dart'; import 'scroll_physics.dart';
...@@ -1283,7 +1284,11 @@ class _DragItemProxy extends StatelessWidget { ...@@ -1283,7 +1284,11 @@ class _DragItemProxy extends StatelessWidget {
final Widget proxyChild = proxyDecorator?.call(child, index, animation.view) ?? child; final Widget proxyChild = proxyDecorator?.call(child, index, animation.view) ?? child;
final Offset overlayOrigin = _overlayOrigin(context); final Offset overlayOrigin = _overlayOrigin(context);
return AnimatedBuilder( return MediaQuery(
// Remove the top padding so that any nested list views in the item
// won't pick up the scaffold's padding in the overlay.
data: MediaQuery.of(context).removePadding(removeTop: true),
child: AnimatedBuilder(
animation: animation, animation: animation,
builder: (BuildContext context, Widget? child) { builder: (BuildContext context, Widget? child) {
Offset effectivePosition = position; Offset effectivePosition = position;
...@@ -1302,6 +1307,7 @@ class _DragItemProxy extends StatelessWidget { ...@@ -1302,6 +1307,7 @@ class _DragItemProxy extends StatelessWidget {
); );
}, },
child: proxyChild, child: proxyChild,
),
); );
} }
} }
......
...@@ -268,6 +268,115 @@ void main() { ...@@ -268,6 +268,115 @@ void main() {
expect(getItemFadeTransition(), findsNothing); expect(getItemFadeTransition(), findsNothing);
}); });
testWidgets('ReorderableList supports items with nested list views without throwing layout exception.', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
builder: (BuildContext context, Widget? child) {
return MediaQuery(
// Ensure there is always a top padding to simulate a phone with
// safe area at the top. If the nested list doesn't have the
// padding removed before it is put into the overlay it will
// overflow the layout by the top padding.
data: MediaQuery.of(context).copyWith(padding: const EdgeInsets.only(top: 50)),
child: child!,
);
},
home: Scaffold(
appBar: AppBar(title: const Text('Nested Lists')),
body: ReorderableList(
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
return ReorderableDragStartListener(
index: index,
key: ValueKey<int>(index),
child: Column(
children: <Widget>[
ListView(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
children: const <Widget>[
Text('Other data'),
Text('Other data'),
Text('Other data'),
],
),
],
),
);
},
onReorder: (int oldIndex, int newIndex) {},
),
),
),
);
// Start gesture on first item
final TestGesture drag = await tester.startGesture(tester.getCenter(find.byKey(const ValueKey<int>(0))));
await tester.pump(kPressTimeout);
// Drag enough for move to start
await drag.moveBy(const Offset(0, 50));
await tester.pumpAndSettle();
// There shouldn't be a layout overflow exception.
expect(tester.takeException(), isNull);
});
testWidgets('ReorderableList supports items with nested list views without throwing layout exception.', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/83224.
await tester.pumpWidget(
MaterialApp(
builder: (BuildContext context, Widget? child) {
return MediaQuery(
// Ensure there is always a top padding to simulate a phone with
// safe area at the top. If the nested list doesn't have the
// padding removed before it is put into the overlay it will
// overflow the layout by the top padding.
data: MediaQuery.of(context).copyWith(padding: const EdgeInsets.only(top: 50)),
child: child!,
);
},
home: Scaffold(
appBar: AppBar(title: const Text('Nested Lists')),
body: ReorderableList(
itemCount: 10,
itemBuilder: (BuildContext context, int index) {
return ReorderableDragStartListener(
index: index,
key: ValueKey<int>(index),
child: Column(
children: <Widget>[
ListView(
shrinkWrap: true,
physics: const ClampingScrollPhysics(),
children: const <Widget>[
Text('Other data'),
Text('Other data'),
Text('Other data'),
],
),
],
),
);
},
onReorder: (int oldIndex, int newIndex) {},
),
),
),
);
// Start gesture on first item.
final TestGesture drag = await tester.startGesture(tester.getCenter(find.byKey(const ValueKey<int>(0))));
await tester.pump(kPressTimeout);
// Drag enough for move to start.
await drag.moveBy(const Offset(0, 50));
await tester.pumpAndSettle();
// There shouldn't be a layout overflow exception.
expect(tester.takeException(), isNull);
});
testWidgets('SliverReorderableList - properly animates the drop at starting position in a reversed list', (WidgetTester tester) async { testWidgets('SliverReorderableList - properly animates the drop at starting position in a reversed list', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/84625 // Regression test for https://github.com/flutter/flutter/issues/84625
final List<int> items = List<int>.generate(8, (int index) => index); final List<int> items = List<int>.generate(8, (int index) => index);
......
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