TextField in a ListView becomes unresponsive (#123734)
TextField in a ListView becomes unresponsive
diff --git a/packages/flutter/lib/src/widgets/tap_and_drag_gestures.dart b/packages/flutter/lib/src/widgets/tap_and_drag_gestures.dart
index 177d625..5d8c337 100644
--- a/packages/flutter/lib/src/widgets/tap_and_drag_gestures.dart
+++ b/packages/flutter/lib/src/widgets/tap_and_drag_gestures.dart
@@ -1218,7 +1218,9 @@
keysPressedOnDown: keysPressedOnDown,
);
- invokeCallback<void>('onDragEnd', () => onDragEnd!(endDetails));
+ if (onDragEnd != null) {
+ invokeCallback<void>('onDragEnd', () => onDragEnd!(endDetails));
+ }
_resetTaps();
_resetDragUpdateThrottle();
diff --git a/packages/flutter/test/widgets/tap_and_drag_gestures_test.dart b/packages/flutter/test/widgets/tap_and_drag_gestures_test.dart
index 32e50e3..b52930c 100644
--- a/packages/flutter/test/widgets/tap_and_drag_gestures_test.dart
+++ b/packages/flutter/test/widgets/tap_and_drag_gestures_test.dart
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
@@ -549,4 +550,42 @@
GestureBinding.instance.gestureArena.sweep(2);
expect(events, <String>['down#1', 'up#1']);
});
+
+ // This is a regression test for https://github.com/flutter/flutter/issues/102084.
+ testGesture('Does not call onDragEnd if not provided', (GestureTester tester) {
+ tapAndDrag = TapAndDragGestureRecognizer()
+ ..dragStartBehavior = DragStartBehavior.down
+ ..maxConsecutiveTap = 3
+ ..onTapDown = (TapDragDownDetails details) {
+ events.add('down#${details.consecutiveTapCount}');
+ };
+
+ FlutterErrorDetails? errorDetails;
+ final FlutterExceptionHandler? oldHandler = FlutterError.onError;
+ FlutterError.onError = (FlutterErrorDetails details) {
+ errorDetails = details;
+ };
+ addTearDown(() {
+ FlutterError.onError = oldHandler;
+ });
+
+ tapAndDrag.addPointer(down5);
+ tester.closeArena(5);
+ tester.route(down5);
+ tester.route(move5);
+ tester.route(up5);
+ GestureBinding.instance.gestureArena.sweep(5);
+ expect(events, <String>['down#1']);
+
+ expect(errorDetails, isNull);
+
+ events.clear();
+ tester.async.elapse(const Duration(milliseconds: 1000));
+ tapAndDrag.addPointer(down1);
+ tester.closeArena(1);
+ tester.route(down1);
+ tester.route(up1);
+ GestureBinding.instance.gestureArena.sweep(1);
+ expect(events, <String>['down#1']);
+ });
}