Fixed DragTarget calling setState after dispose. (#6150)
DragTarget would call setState after it was disposed in didLeave and didDrop. Fixes #6128.
This commit is contained in:
@@ -316,6 +316,8 @@ class _DragTargetState<T> extends State<DragTarget<T>> {
|
||||
|
||||
void didLeave(dynamic data) {
|
||||
assert(_candidateData.contains(data) || _rejectedData.contains(data));
|
||||
if (!mounted)
|
||||
return;
|
||||
setState(() {
|
||||
_candidateData.remove(data);
|
||||
_rejectedData.remove(data);
|
||||
@@ -324,6 +326,8 @@ class _DragTargetState<T> extends State<DragTarget<T>> {
|
||||
|
||||
void didDrop(dynamic data) {
|
||||
assert(_candidateData.contains(data));
|
||||
if (!mounted)
|
||||
return;
|
||||
setState(() {
|
||||
_candidateData.remove(data);
|
||||
});
|
||||
|
||||
@@ -913,6 +913,7 @@ void main() {
|
||||
expect(didTap, isFalse);
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/6128.
|
||||
testWidgets('Draggable plays nice with onTap', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(new Overlay(
|
||||
initialEntries: <OverlayEntry>[
|
||||
@@ -944,6 +945,65 @@ void main() {
|
||||
await firstGesture.moveBy(new Offset(100.0, 0.0));
|
||||
await secondGesture.up();
|
||||
});
|
||||
|
||||
testWidgets('DragTarget does not set state when remove from the tree', (WidgetTester tester) async {
|
||||
List<String> events = <String>[];
|
||||
Point firstLocation, secondLocation;
|
||||
|
||||
await tester.pumpWidget(new MaterialApp(
|
||||
home: new Column(
|
||||
children: <Widget>[
|
||||
new Draggable<int>(
|
||||
data: 1,
|
||||
child: new Text('Source'),
|
||||
feedback: new Text('Dragging')
|
||||
),
|
||||
new DragTarget<int>(
|
||||
builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
|
||||
return new Text('Target');
|
||||
},
|
||||
onAccept: (int data) {
|
||||
events.add('drop');
|
||||
}
|
||||
),
|
||||
]
|
||||
)
|
||||
));
|
||||
|
||||
expect(events, isEmpty);
|
||||
expect(find.text('Source'), findsOneWidget);
|
||||
expect(find.text('Target'), findsOneWidget);
|
||||
|
||||
expect(events, isEmpty);
|
||||
await tester.tap(find.text('Source'));
|
||||
expect(events, isEmpty);
|
||||
|
||||
firstLocation = tester.getCenter(find.text('Source'));
|
||||
TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
|
||||
await tester.pump();
|
||||
|
||||
await tester.pump(const Duration(seconds: 20));
|
||||
|
||||
secondLocation = tester.getCenter(find.text('Target'));
|
||||
await gesture.moveTo(secondLocation);
|
||||
await tester.pump();
|
||||
|
||||
await tester.pumpWidget(new MaterialApp(
|
||||
home: new Column(
|
||||
children: <Widget>[
|
||||
new Draggable<int>(
|
||||
data: 1,
|
||||
child: new Text('Source'),
|
||||
feedback: new Text('Dragging')
|
||||
),
|
||||
]
|
||||
)
|
||||
));
|
||||
|
||||
expect(events, isEmpty);
|
||||
await gesture.up();
|
||||
await tester.pump();
|
||||
});
|
||||
}
|
||||
|
||||
class DragTargetData { }
|
||||
|
||||
Reference in New Issue
Block a user