Do not crash when dragging ReorderableListView with two fingers simultaneously (#88508)
This commit is contained in:
parent
d6dd2fa78d
commit
58409c1901
@ -522,6 +522,7 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
|
|||||||
int? _insertIndex;
|
int? _insertIndex;
|
||||||
Offset? _finalDropPosition;
|
Offset? _finalDropPosition;
|
||||||
MultiDragGestureRecognizer? _recognizer;
|
MultiDragGestureRecognizer? _recognizer;
|
||||||
|
int? _recognizerPointer;
|
||||||
bool _autoScrolling = false;
|
bool _autoScrolling = false;
|
||||||
// To implement the gap for the dragged item, we replace the dragged item
|
// To implement the gap for the dragged item, we replace the dragged item
|
||||||
// with a zero sized box, and then translate all of the later items down
|
// with a zero sized box, and then translate all of the later items down
|
||||||
@ -579,12 +580,18 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
|
|||||||
setState(() {
|
setState(() {
|
||||||
if (_dragInfo != null) {
|
if (_dragInfo != null) {
|
||||||
cancelReorder();
|
cancelReorder();
|
||||||
|
} else if (_recognizer != null && _recognizerPointer != event.pointer) {
|
||||||
|
_recognizer!.dispose();
|
||||||
|
_recognizer = null;
|
||||||
|
_recognizerPointer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_items.containsKey(index)) {
|
if (_items.containsKey(index)) {
|
||||||
_dragIndex = index;
|
_dragIndex = index;
|
||||||
_recognizer = recognizer
|
_recognizer = recognizer
|
||||||
..onStart = _dragStart
|
..onStart = _dragStart
|
||||||
..addPointer(event);
|
..addPointer(event);
|
||||||
|
_recognizerPointer = event.pointer;
|
||||||
} else {
|
} else {
|
||||||
// TODO(darrenaustin): Can we handle this better, maybe scroll to the item?
|
// TODO(darrenaustin): Can we handle this better, maybe scroll to the item?
|
||||||
throw Exception('Attempting to start a drag on a non-visible item');
|
throw Exception('Attempting to start a drag on a non-visible item');
|
||||||
|
@ -7,6 +7,53 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
// Regression test for https://github.com/flutter/flutter/issues/88191
|
||||||
|
testWidgets('Do not crash when dragging with two fingers simultaneously', (WidgetTester tester) async {
|
||||||
|
final List<int> items = List<int>.generate(3, (int index) => index);
|
||||||
|
void handleReorder(int fromIndex, int toIndex) {
|
||||||
|
if (toIndex > fromIndex) {
|
||||||
|
toIndex -= 1;
|
||||||
|
}
|
||||||
|
items.insert(toIndex, items.removeAt(fromIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
home: ReorderableList(
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return ReorderableDragStartListener(
|
||||||
|
index: index,
|
||||||
|
key: ValueKey<int>(items[index]),
|
||||||
|
child: SizedBox(
|
||||||
|
height: 100,
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: <Widget>[
|
||||||
|
Text('item ${items[index]}'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: items.length,
|
||||||
|
onReorder: handleReorder,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
final TestGesture drag1 = await tester.startGesture(tester.getCenter(find.text('item 0')));
|
||||||
|
final TestGesture drag2 = await tester.startGesture(tester.getCenter(find.text('item 0')));
|
||||||
|
await tester.pump(kLongPressTimeout);
|
||||||
|
|
||||||
|
await drag1.moveBy(const Offset(0, 100));
|
||||||
|
await drag2.moveBy(const Offset(0, 100));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
await drag1.up();
|
||||||
|
await drag2.up();
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(tester.takeException(), isNull);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('negative itemCount should assert', (WidgetTester tester) async {
|
testWidgets('negative itemCount should assert', (WidgetTester tester) async {
|
||||||
final List<int> items = <int>[1, 2, 3];
|
final List<int> items = <int>[1, 2, 3];
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user