Unverified Commit f4604fe0 authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

Fix `SliverReorderableList` item dispose (#105097)

parent b0edb5e7
......@@ -603,8 +603,7 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
@override
void dispose() {
_dragInfo?.dispose();
_autoScroller?.stopAutoScroll();
_dragReset();
super.dispose();
}
......@@ -658,7 +657,9 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
///
/// If no drag is active, this will do nothing.
void cancelReorder() {
_dragReset();
setState(() {
_dragReset();
});
}
void _registerItem(_ReorderableItemState item) {
......@@ -724,7 +725,9 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
}
void _dragCancel(_DragInfo item) {
_dragReset();
setState(() {
_dragReset();
});
}
void _dragEnd(_DragInfo item) {
......@@ -753,29 +756,29 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
if (fromIndex != toIndex) {
widget.onReorder.call(fromIndex, toIndex);
}
_dragReset();
setState(() {
_dragReset();
});
}
void _dragReset() {
setState(() {
if (_dragInfo != null) {
if (_dragIndex != null && _items.containsKey(_dragIndex)) {
final _ReorderableItemState dragItem = _items[_dragIndex!]!;
dragItem._dragging = false;
dragItem.rebuild();
_dragIndex = null;
}
_dragInfo?.dispose();
_dragInfo = null;
_autoScroller?.stopAutoScroll();
_resetItemGap();
_recognizer?.dispose();
_recognizer = null;
_overlayEntry?.remove();
_overlayEntry = null;
_finalDropPosition = null;
if (_dragInfo != null) {
if (_dragIndex != null && _items.containsKey(_dragIndex)) {
final _ReorderableItemState dragItem = _items[_dragIndex!]!;
dragItem._dragging = false;
dragItem.rebuild();
_dragIndex = null;
}
});
_dragInfo?.dispose();
_dragInfo = null;
_autoScroller?.stopAutoScroll();
_resetItemGap();
_recognizer?.dispose();
_recognizer = null;
_overlayEntry?.remove();
_overlayEntry = null;
_finalDropPosition = null;
}
}
void _resetItemGap() {
......
......@@ -1005,6 +1005,73 @@ void main() {
expect(items, orderedEquals(<int>[0, 1, 2, 3, 4]));
});
});
testWidgets('SliverReorderableList properly disposes items', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/105010
const int itemCount = 5;
final List<int> items = List<int>.generate(itemCount, (int index) => index);
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
appBar: AppBar(),
drawer: Drawer(
child: Builder(
builder: (BuildContext context) {
return Column(
children: <Widget>[
Expanded(
child: CustomScrollView(
slivers: <Widget>[
SliverReorderableList(
itemCount: itemCount,
itemBuilder: (BuildContext context, int index) {
return Material(
key: ValueKey<String>('item-$index'),
child: ReorderableDragStartListener(
index: index,
child: ListTile(
title: Text('item ${items[index]}'),
),
),
);
},
onReorder: (int oldIndex, int newIndex) {},
),
],
),
),
TextButton(
onPressed: () {
Scaffold.of(context).closeDrawer();
},
child: const Text('Close drawer'),
),
],
);
}
),
),
),
),
);
await tester.tap(find.byIcon(Icons.menu));
await tester.pumpAndSettle();
final Finder item0 = find.text('item 0');
expect(item0, findsOneWidget);
// Start gesture on first item without drag up event.
final TestGesture drag = await tester.startGesture(tester.getCenter(item0));
await drag.moveBy(const Offset(0, 200));
await tester.pump();
await tester.tap(find.text('Close drawer'));
await tester.pumpAndSettle();
expect(item0, findsNothing);
});
}
class TestList extends StatefulWidget {
......
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