This tutorial shows you how to use GestureDetector
in Flutter.
If you need to detect what kind of gesture is happening on a widget, the easiest way is by wrapping the widget as the child of GestureDetector
. It's a StatelessWidget
that can have a lot of callback functions each for different types of gestures. It supports various types of gestures such as tap, secondary tap, long press, vertical/horizontal drag, pan, and scale. Below are the examples of how to use Flutter's GestureDetector
along with explanations for each supported gesture type.
Using GestureDetector
Flutter's GestureDetector
constructor has a lot of parameters. Most of them are callback functions each for handling a specific gesture tpe. There is no required parameter.
GestureDetector({
Key key,
this.child,
this.onTapDown,
this.onTapUp,
this.onTap,
this.onTapCancel,
this.onSecondaryTap,
this.onSecondaryTapDown,
this.onSecondaryTapUp,
this.onSecondaryTapCancel,
this.onDoubleTap,
this.onLongPress,
this.onLongPressStart,
this.onLongPressMoveUpdate,
this.onLongPressUp,
this.onLongPressEnd,
this.onSecondaryLongPress,
this.onSecondaryLongPressStart,
this.onSecondaryLongPressMoveUpdate,
this.onSecondaryLongPressUp,
this.onSecondaryLongPressEnd,
this.onVerticalDragDown,
this.onVerticalDragStart,
this.onVerticalDragUpdate,
this.onVerticalDragEnd,
this.onVerticalDragCancel,
this.onHorizontalDragDown,
this.onHorizontalDragStart,
this.onHorizontalDragUpdate,
this.onHorizontalDragEnd,
this.onHorizontalDragCancel,
this.onForcePressStart,
this.onForcePressPeak,
this.onForcePressUpdate,
this.onForcePressEnd,
this.onPanDown,
this.onPanStart,
this.onPanUpdate,
this.onPanEnd,
this.onPanCancel,
this.onScaleStart,
this.onScaleUpdate,
this.onScaleEnd,
this.behavior,
this.excludeFromSemantics = false,
this.dragStartBehavior = DragStartBehavior.start,
})
Usually, you need to have a Widget
passed as child
and pass at least one callback function depending on what gestures types you want to handle.
GestureDetector(
onTap: () {
print('onTap');
Feedback.forTap(context);
},
onLongPress: () {
print('onLongPress');
Feedback.forLongPress(context);
},
child: RaisedButton(
child: Text('Click'),
),
)
Handling Specific Gestures
Below are the examples of callback functions for each gesture type. Some of them have a parameter that allows you to get the detail of the gesture.
Using onTapDown
onTapDown
is triggered when a pointer has started to contact the screen at a particular location. It doesn't wait until the tap gesture wins. It has a parameter of type TapDownDetails
.
onTapDown: (TapDownDetails tapDownDetails) {
// Write the actions here
}
Using onTapUp
onTapUp
is triggered when a pointer has stopped to contact the screen at a particular location, just before onTap
(if tap gesture wins) or onTapCancel
(if tap gesture doesn't win). It has a parameter of type TapUpDetails
.
onTapUp: (TapUpDetails tapUpDetails) {
// Write the actions here
}
Using onTap
onTap
is triggered when a tap gesture has occured and wins.
onTap: () {
// Write the actions here
}
Using onTapCancel
onTapCancel
is triggered when a pointer that caused onTapDown
doesn't end up causing a complete tap. For example, if the pointer has been moved outside the tap area when it's released.
onTapCancel: () {
// Write the actions here
}
Using onSecondaryTap
onSecondaryTap
is triggered when a tap with secondary button has occured and wins.
onSecondaryTap: () {
// Write the actions here
}
Using onSecondaryTapDown
onSecondaryTapDown
is triggered when a pointer with a secondary button has started to contact the screen at a particular location. It doesn't wait until the tap gesture wins. It has a parameter of type TapDownDetails
.
onSecondaryTapDown: (TapDownDetails tapDownDetails) {
// Write the actions here
}
Using onSecondaryTapUp
onSecondaryTapUp
is triggered when a pointer with a secondary button has stopped to contact the screen at a particular location, just before onSecondaryTap
(if tap gesture wins) or onSecondaryTapCancel
(if tap gesture doesn't win). It has a parameter of type TapUpDetails
.
onSecondaryTapUp: (TapUpDetails tapUpDetails) {
// Write the actions here
}
Using onSecondaryTapCancel
onSecondaryTapCancel
is triggered when a pointer that caused onSecondaryTapDown
doesn't end up causing a complete tap. For example, if the pointer has been moved outside the tap area when it's released.
onSecondaryTapCancel: () {
// Write the actions here
}
Using onDoubleTap
onDoubleTap is triggered when the user does two quick taps in succession at the same location.
onDoubleTap: () {
// Write the actions here
}
Using onLongPress
onLongPress
is triggered when a pointer of a primary button has remained in contact at a particular location for a long period.
onLongPress: () {
// Write the actions here
}
Using onLongPressStart
onLongPressStart
is triggered when a pointer of a primary button has remained in contact at a particular location for a long period. It has a parameter of type LongPressStartDetails
.
onLongPressStart: (LongPressStartDetails longPressStartDetails) {
// Write the actions here
}
Using onLongPressMoveUpdate
onLongPressMoveUpdate
is triggered when a pointer has been moved after a long press with a primary button. It has a parameter of type LongPressMoveUpdateDetails
.
onLongPressMoveUpdate: (LongPressMoveUpdateDetails longPressMoveUpdateDetails) {
// Write the actions here
}
Using onLongPressUp
onLongPressUp
is triggered when a pointer of a primary button has stopped to contact the screen at a particular location after a long press.
onLongPressUp: () {
// Write the actions here
}
Using onLongPressEnd
onLongPressEnd
is triggered when a pointer of a primary button has stopped to contact the screen at a particular location after a long press. It has a parameter of type LongPressEndDetails
.
onLongPressEnd: (LongPressEndDetails longPressEndDetails) {
// Write the actions here
}
Using onSecondaryLongPress
onSecondaryLongPress
is triggered when a pointer of a secondary button has remained in contact at a particular location for a long period.
onSecondaryLongPress: () {
// Write the actions here
}
Using onSecondaryLongPressStart
onSecondaryLongPressStart
is triggered when a pointer of a secondary button has remained in contact at a particular location for a long period. It has a parameter of type LongPressStartDetails
.
onSecondaryLongPressStart: (LongPressStartDetails longPressStartDetails) {
// Write the actions here
}
Using onSecondaryLongPressMoveUpdate
onSecondaryLongPressMoveUpdate
is triggered when a pointer has been moved after a long press with a secondary button. It has a parameter of type LongPressMoveUpdateDetails
.
onSecondaryLongPressMoveUpdate: (LongPressMoveUpdateDetails longPressMoveUpdateDetails) {
// Write the actions here
}
Using onSecondaryLongPressUp
onSecondaryLongPressUp
is triggered when a pointer of a secondary button has stopped to contact the screen at a particular location after a long press.
onSecondaryLongPressUp: () {
// Write the actions here
}
Using onSecondaryLongPressEnd
onSecondaryLongPressEnd
is triggered when a pointer of a secondary button has stopped to contact the screen at a particular location after a long press.
onSecondaryLongPressEnd: () {
// Write the actions here
}
Using onVerticalDragDown
onVerticalDragDown
is triggered when a pointer of a primary button has contacted the screen and might begin to move vertically. It has a parameter of type DragDownDetails
.
onVerticalDragDown: (DragDownDetails dragDownDetails) {
// Write the actions here
}
Using onVerticalDragStart
onVerticalDragStart
is triggered when a pointer of a primary button has contacted the screen and has begun to move vertically. It has a parameter of type DragStartDetails
.
onVerticalDragStart: (DragStartDetails dragStartDetails) {
// Write the actions here
}
Using onVerticalDragUpdate
onVerticalDragUpdate
is triggered when a pointer of a primary button has contacted the screen and is moving veritcally. It has a parameter of type DragUpdateDetails
.
onVerticalDragUpdate: (DragUpdateDetails dragUpdateDetails) {
// Write the actions here
}
Using onVerticalDragEnd
onVerticalDragEnd
is triggered when a pointer of a primary button that was moving vertically has stopped to contact the screen at a specific velocity. It has a parameter of type DragEndDetails
.
onVerticalDragEnd: (DragEndDetails dragEndDetails) {
// Write the actions here
}
Using onVerticalDragCancel
onVerticalDragCancel
is triggered when a pointer that had triggered onVerticalDragDown
doesn't complete.
onVerticalDragCancel: () {
// Write the actions here
}
Using onHorizontalDragDown
onHorizontalDragDown
is triggered when a pointer of a primary button has contacted the screen and might begin to move horizontally. It has a parameter of type DragDownDetails
.
onHorizontalDragDown: (DragDownDetails dragDownDetails) {
// Write the actions here
}
Using onHorizontalDragStart
onHorizontalDragStart
is triggered when a pointer of a primary button has contacted the screen and has begun to move horizontally. It has a parameter of type DragStartDetails
.
onHorizontalDragStart: (DragStartDetails dragStartDetails) {
// Write the actions here
}
Using onHorizontalDragUpdate
onHorizontalDragUpdate
is triggered when a pointer of a primary button has contacted the screen and is moving horizontally. It has a parameter of type DragUpdateDetails
.
onHorizontalDragUpdate: (DragUpdateDetails dragUpdateDetails) {
// Write the actions here
}
Using onHorizontalDragEnd
onHorizontalDragEnd
is triggered when a pointer of a primary button that was moving vertically has stopped to contact the screen at a specific velocity. It has a parameter of type DragEndDetails
.
onHorizontalDragEnd: (DragEndDetails dragEndDetails) {
// Write the actions here
}
Using onHorizontalDragCancel
onHorizontalDragCancel
is triggered when a pointer that had triggered onHorizontalDragDown
doesn't complete.
onHorizontalDragCancel: () {
// Write the actions here
}
Using onForcePressStart
onForcePressStart
is triggered when a pointer has pressed with sufficient force to initiate a force press with an amount of at least ForcePressGestureRecognizer.startPressure
. It has a parameter of type ForcePressDetails
.
onForcePressStart: (ForcePressDetails forcePressDetails) {
// Write the actions here
}
Using onForcePressPeak
onForcePressPeak
is triggered when a pointer has pressed with the maximum force with an amount of at least ForcePressGestureRecognizer.startPressure
. It has a parameter of type ForcePressDetails
.
onForcePressPeak: (ForcePressDetails forcePressDetails) {
// Write the actions here
}
Using onForcePressUpdate
onForcePressUpdate
is triggered when a pointer has passed ForcePressGestureRecognizer.startPressure
and is moving on the screen. It has a parameter of type ForcePressDetails
.
onForcePressUpdate: (ForcePressDetails forcePressDetails) {
// Write the actions here
}
Using onForcePressEnd
onForcePressUpdate
is triggered when a pointer had passed ForcePressGestureRecognizer.startPressure
and no longer in contact with the screen. It has a parameter of type ForcePressDetails
.
onForcePressEnd: (ForcePressDetails forcePressDetails) {
// Write the actions here
}
Using onPanDown
onPanDown
is triggered when a pointer has contacted the screen with a primary button and might begin to move. It has a parameter of type DragDownDetails
.
onPanDown: (DragDownDetails dragDownDetails) {
// Write the actions here
}
Using onPanStart
onPanStart
is triggered when a pointer has contacted the screen with a primary button and has begun to move. It has a parameter of type DragStartDetails
.
onPanStart: (DragStartDetails dragStartDetails) {
// Write the actions here
}
Using onPanUpdate
onPanUpdate
is triggered when a pointer has contacted the screen with a primary button and is moving. It has a parameter of type DragUpdateDetails
.
onPanUpdate: (DragUpdateDetails dragUpdateDetails) {
// Write the actions here
}
Using onPanEnd
onPanEnd
is triggered when a pointer of a primary button that was moving has stopped to contact the screen at a specific velocity. It has a parameter of type DragEndDetails
.
onTap: (DragEndDetails dragEndDetails) {
// Write the actions here
}
Using onPanCancel
onPanCancel
is triggered when a pointer that had triggered onPanDown
doesn't complete.
onPanCancel: () {
// Write the actions here
}
Using onScaleStart
onScaleStart
is triggered when a pointer has established a focal point and initial scale of 1.0. It has a parameter of type ScaleStartDetails
.
onScaleStart: (ScaleStartDetails scaleStartDetails) {
// Write the actions here
}
Using onScaleUpdate
onScaleUpdate
is triggered when a pointer has a new focal point. It has a parameter of type ScaleUpdateDetails
.
onScaleUpdate: (ScaleUpdateDetails scaleUpdateDetails) {
// Write the actions here
}
Using onScaleEnd
onScaleEnd
is triggered when a pointer has a new focal point. It has a parameter of type ScaleEndDetails
.
onScaleEnd: (ScaleEndDetails scaleEndDetails) {
// Write the actions here
}
Gesture Detail Classes
On the previous section, you can see that there are some callback function that accepts a parameter that allows you to get a more detailed information. Some of them have parameter of the same type. Below are the properties of the classes used as parameter.
TapDownDetails
Offset globalPosition
: The global position at which the pointer contacted the screen.PointerDeviceKind kind
: The kind of the device that initiated the event.Offset localPosition
: The local position at which the pointer contacted the screen.
TapUpDetails
Offset globalPosition
: The global position at which the pointer contacted the screen.Offset localPosition
: The local position at which the pointer contacted the screen.
LongPressStartDetails
Offset globalPosition
: The global position at which the pointer contacted the screen.Offset localPosition
: The local position at which the pointer contacted the screen.
LongPressMoveUpdateDetails
Offset globalPosition
: The global position at which the pointer contacted the screen.Offset localPosition
: The local position at which the pointer contacted the screen.Offset offsetFromOrigin
: A delta offset from the point where the long press drag initially contacted the screen to the point where the pointer is currently located.Offset localOffsetFromOrigin
: A local delta offset from the point where the long press drag initially contacted the screen to the point where the pointer is currently located.
LongPressEndDetails
Offset globalPosition
: The global position at which the pointer contacted the screen.Offset localPosition
: The local position at which the pointer contacted the screen.Velocity velocity
: The pointer's velocity when it stopped contacting the screen.
DragDownDetails
Offset globalPosition
: The global position at which the pointer contacted the screen.Offset localPosition
: The local position in the coordinate system of the event receiver at which the pointer contacted the screen.
DragStartDetails
Offset globalPosition
: The global position at which the pointer contacted the screen.Offset localPosition
: The local position in the coordinate system of the event receiver at which the pointer contacted the screen.Duration sourceTimeStamp
: Recorded timestamp of the source pointer event that triggered the drag event.
DragUpdateDetails
Duration sourceTimeStamp
: Recorded timestamp of the source pointer event that triggered the drag event..Offset delta
: The amount the pointer has moved in the coordinate space of the event receiver since the previous update..double primaryDelta
: The amount the pointer has moved along the primary axis in the coordinate space of the event receiver since the previous update..Offset globalPosition
: The pointer's global position when it triggered this update.Offset localPosition
: The local position in the coordinate system of the event receiver at which the pointer contacted the screen.
DragEndDetails
Velocity velocity
: The velocity the pointer was moving when it stopped contacting the screen.double primaryVelocity
: The velocity the pointer was moving along the primary axis when it stopped contacting the screen, in logical pixels per second.
ScaleStartDetails
Offset focalPoint
: The initial focal point of the pointers in contact with the screen.Offset localFocalPoint
: The initial focal point of the pointers in contact with the screen.
ScaleUpdateDetails
Offset focalPoint
: The focal point of the pointers in contact with the screen.Offset localFocalPoint
: The focal point of the pointers in contact with the screen.double scale
: The scale implied by the average distance between the pointers in contact with the screen.double horizontalScale
: The scale implied by the average distance along the horizontal axis between the pointers in contact with the screen.double verticalScale
: The scale implied by the average distance along the vertical axis between the pointers in contact with the screen.double rotation
: The angle implied by the first two pointers to enter in contact with the screen.
ScaleEndDetails
Velocity velocity
: The velocity of the last pointer to be lifted off of the screen.
ForcePressDetails
Offset globalPosition
: The global position at which the function was called.Offset localPosition
: The local position at which the function was called.double pressure
: The pressure of the pointer on the screen.
GestureDetector
Properties
Below are the properties of GestureDetector
excluding the properties for handling specific gesture types as they're already explained above.
Key key
: The widget's key, used to control if it should be replaced.Widget child
: The widget below this widget in the tree.HitTestBehavior behavior
: How this gesture detector should behave during hit testing.bool excludeFromSemantics
: Whether to exclude these gestures from the semantics tree.DragStartBehavior dragStartBehavior
: Determines the way that drag start behavior is handled. Defaults toDragStartBehavior.start
.
Full Code
Here's the full code example that uses GestureDetector
for detecting tap and long press.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Woolha.com Flutter Tutorial',
home: _GestureDetectorExample(),
);
}
}
class _GestureDetectorExample extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Woolha.com Flutter Tutorial'),
),
body: Center(
child: GestureDetector(
onTap: () {
print('onTap');
Feedback.forTap(context);
},
onLongPress: () {
print('onLongPress');
Feedback.forLongPress(context);
},
child: RaisedButton(
child: Text('Click'),
),
),
),
);
}
}