Unverified Commit c12b99f2 authored by jslavitz's avatar jslavitz Committed by GitHub

Adds callback for Long Press Up (#22822)

* add onLongPressUp geasture which is fired when a long-press ends
parent 6b79d377
...@@ -11,28 +11,48 @@ import 'recognizer.dart'; ...@@ -11,28 +11,48 @@ import 'recognizer.dart';
/// same location for a long period of time. /// same location for a long period of time.
typedef GestureLongPressCallback = void Function(); typedef GestureLongPressCallback = void Function();
/// Signature for when a pointer stops contacting the screen after a long press gesture was detected.
typedef GestureLongPressUpCallback = void Function();
/// Recognizes when the user has pressed down at the same location for a long /// Recognizes when the user has pressed down at the same location for a long
/// period of time. /// period of time.
class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer { class LongPressGestureRecognizer extends PrimaryPointerGestureRecognizer {
/// Creates a long-press gesture recognizer. /// Creates a long-press gesture recognizer.
/// ///
/// Consider assigning the [onLongPress] callback after creating this object. /// Consider assigning the [onLongPress] callback after creating this object.
LongPressGestureRecognizer({ Object debugOwner }) : super(deadline: kLongPressTimeout, debugOwner: debugOwner); LongPressGestureRecognizer({ Object debugOwner })
: super(deadline: kLongPressTimeout, debugOwner: debugOwner);
bool _longPressAccepted = false;
/// Called when a long-press is recognized. /// Called when a long press gesture has been recognized.
GestureLongPressCallback onLongPress; GestureLongPressCallback onLongPress;
/// Called when the pointer stops contacting the screen after the long-press gesture has been recognized.
GestureLongPressUpCallback onLongPressUp;
@override @override
void didExceedDeadline() { void didExceedDeadline() {
resolve(GestureDisposition.accepted); resolve(GestureDisposition.accepted);
if (onLongPress != null) _longPressAccepted = true;
if (onLongPress != null) {
invokeCallback<void>('onLongPress', onLongPress); invokeCallback<void>('onLongPress', onLongPress);
}
} }
@override @override
void handlePrimaryPointer(PointerEvent event) { void handlePrimaryPointer(PointerEvent event) {
if (event is PointerUpEvent) if (event is PointerUpEvent) {
resolve(GestureDisposition.rejected); if (_longPressAccepted == true && onLongPressUp != null) {
_longPressAccepted = false;
invokeCallback<void>('onLongPressUp', onLongPressUp);
} else {
resolve(GestureDisposition.rejected);
}
} else if (event is PointerDownEvent || event is PointerCancelEvent) {
// the first touch, initialize the flag with false
_longPressAccepted = false;
}
} }
@override @override
......
...@@ -150,6 +150,7 @@ class GestureDetector extends StatelessWidget { ...@@ -150,6 +150,7 @@ class GestureDetector extends StatelessWidget {
this.onTapCancel, this.onTapCancel,
this.onDoubleTap, this.onDoubleTap,
this.onLongPress, this.onLongPress,
this.onLongPressUp,
this.onVerticalDragDown, this.onVerticalDragDown,
this.onVerticalDragStart, this.onVerticalDragStart,
this.onVerticalDragUpdate, this.onVerticalDragUpdate,
...@@ -242,6 +243,9 @@ class GestureDetector extends StatelessWidget { ...@@ -242,6 +243,9 @@ class GestureDetector extends StatelessWidget {
/// a long period of time. /// a long period of time.
final GestureLongPressCallback onLongPress; final GestureLongPressCallback onLongPress;
/// A pointer that has triggered a long-press has stopped contacting the screen.
final GestureLongPressUpCallback onLongPressUp;
/// A pointer has contacted the screen and might begin to move vertically. /// A pointer has contacted the screen and might begin to move vertically.
final GestureDragDownCallback onVerticalDragDown; final GestureDragDownCallback onVerticalDragDown;
...@@ -348,12 +352,13 @@ class GestureDetector extends StatelessWidget { ...@@ -348,12 +352,13 @@ class GestureDetector extends StatelessWidget {
); );
} }
if (onLongPress != null) { if (onLongPress != null || onLongPressUp !=null) {
gestures[LongPressGestureRecognizer] = GestureRecognizerFactoryWithHandlers<LongPressGestureRecognizer>( gestures[LongPressGestureRecognizer] = GestureRecognizerFactoryWithHandlers<LongPressGestureRecognizer>(
() => LongPressGestureRecognizer(debugOwner: this), () => LongPressGestureRecognizer(debugOwner: this),
(LongPressGestureRecognizer instance) { (LongPressGestureRecognizer instance) {
instance instance
..onLongPress = onLongPress; ..onLongPress = onLongPress
..onLongPressUp = onLongPressUp;
}, },
); );
} }
......
...@@ -137,4 +137,25 @@ void main() { ...@@ -137,4 +137,25 @@ void main() {
drag.dispose(); drag.dispose();
}); });
testGesture('Should recognize long press up', (GestureTester tester) {
final LongPressGestureRecognizer longPress = LongPressGestureRecognizer();
bool longPressUpRecognized = false;
longPress.onLongPressUp = () {
longPressUpRecognized = true;
};
longPress.addPointer(down);
tester.closeArena(5);
expect(longPressUpRecognized, isFalse);
tester.route(down); // kLongPressTimeout = 500;
expect(longPressUpRecognized, isFalse);
tester.async.elapse(const Duration(milliseconds: 300));
expect(longPressUpRecognized, isFalse);
tester.async.elapse(const Duration(milliseconds: 700));
tester.route(up);
expect(longPressUpRecognized, isTrue);
longPress.dispose();
});
} }
...@@ -314,4 +314,33 @@ void main() { ...@@ -314,4 +314,33 @@ void main() {
expect(tap, 0); expect(tap, 0);
expect(longPress, 1); expect(longPress, 1);
}); });
testWidgets('Long Press Up Callback called after long press', (WidgetTester tester) async {
int longPressUp = 0;
await tester.pumpWidget(
Container(
alignment: Alignment.topLeft,
child: Container(
alignment: Alignment.center,
height: 100.0,
color: const Color(0xFF00FF00),
child: GestureDetector(
onLongPressUp: () {
longPressUp += 1;
},
),
),
),
);
Future<Null> longPress(Duration timeout) async {
final TestGesture gesture = await tester.startGesture(const Offset(400.0, 50.0));
await tester.pump(timeout);
await gesture.up();
}
await longPress(kLongPressTimeout + Duration(seconds: 1)); // To make sure the time for long press has occured
expect(longPressUp, 1);
});
} }
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