GestureDetector class Null safety

A widget that detects gestures.

Attempts to recognize gestures that correspond to its non-null callbacks.

If this widget has a child, it defers to that child for its sizing behavior. If it does not have a child, it grows to fit the parent instead.

By default a GestureDetector with an invisible child ignores touches; this behavior can be controlled with behavior.

GestureDetector also listens for accessibility events and maps them to the callbacks. To ignore accessibility events, set excludeFromSemantics to true.

See flutter.dev/gestures/ for additional information.

Material design applications typically react to touches with ink splash effects. The InkWell class implements this effect and can be used in place of a GestureDetector for handling taps.

This example contains a black light bulb wrapped in a GestureDetector. It turns the light bulb yellow when the "TURN LIGHT ON" button is tapped by setting the _lights field, and off again when "TURN LIGHT OFF" is tapped.
To create a local project with this code sample, run:
flutter create --sample=widgets.GestureDetector.1 mysample

This example uses a Container that wraps a GestureDetector widget which detects a tap.

Since the GestureDetector does not have a child, it takes on the size of its parent, making the entire area of the surrounding Container clickable. When tapped, the Container turns yellow by setting the _color field. When tapped again, it goes back to white.

To create a local project with this code sample, run:
flutter create --sample=widgets.GestureDetector.2 mysample

Troubleshooting

Why isn't my parent GestureDetector.onTap method called?

Given a parent GestureDetector with an onTap callback, and a child GestureDetector that also defines an onTap callback, when the inner GestureDetector is tapped, both GestureDetectors send a GestureRecognizer into the gesture arena. This is because the pointer coordinates are within the bounds of both GestureDetectors. The child GestureDetector wins in this scenario because it was the first to enter the arena, resolving as first come, first served. The child onTap is called, and the parent's is not as the gesture has been consumed. For more information on gesture disambiguation see: Gesture disambiguation.

Setting GestureDetector.behavior to HitTestBehavior.opaque or HitTestBehavior.translucent has no impact on parent-child relationships: both GestureDetectors send a GestureRecognizer into the gesture arena, only one wins.

Some callbacks (e.g. onTapDown) can fire before a recognizer wins the arena, and others (e.g. onTapCancel) fire even when it loses the arena. Therefore, the parent detector in the example above may call some of its callbacks even though it loses in the arena.

This example uses a GestureDetector that wraps a green Container and a second GestureDetector that wraps a yellow Container. The second GestureDetector is a child of the green Container. Both GestureDetectors define an onTap callback. When the callback is called it adds a red border to the corresponding Container.

When the green Container is tapped, it's parent GestureDetector enters the gesture arena. It wins because there is no competing GestureDetector and the green Container shows a red border. When the yellow Container is tapped, it's parent GestureDetector enters the gesture arena. The GestureDetector that wraps the green Container also enters the gesture arena (the pointer events coordinates are inside both GestureDetectors bounds). The GestureDetector that wraps the yellow Container wins because it was the first detector to enter the arena.

This example sets debugPrintGestureArenaDiagnostics to true. This flag prints useful information about gesture arenas.

Changing the GestureDetector.behavior property to HitTestBehavior.translucent or HitTestBehavior.opaque has no impact: both GestureDetectors send a GestureRecognizer into the gesture arena, only one wins.

To create a local project with this code sample, run:
flutter create --sample=widgets.GestureDetector.3 mysample

Debugging

To see how large the hit test box of a GestureDetector is for debugging purposes, set debugPaintPointersEnabled to true.

See also:

  • Listener, a widget for listening to lower-level raw pointer events.
  • MouseRegion, a widget that tracks the movement of mice, even when no button is pressed.
  • RawGestureDetector, a widget that is used to detect custom gestures.
Inheritance

Constructors

GestureDetector({Key? key, Widget? child, GestureTapDownCallback? onTapDown, GestureTapUpCallback? onTapUp, GestureTapCallback? onTap, GestureTapCancelCallback? onTapCancel, GestureTapCallback? onSecondaryTap, GestureTapDownCallback? onSecondaryTapDown, GestureTapUpCallback? onSecondaryTapUp, GestureTapCancelCallback? onSecondaryTapCancel, GestureTapDownCallback? onTertiaryTapDown, GestureTapUpCallback? onTertiaryTapUp, GestureTapCancelCallback? onTertiaryTapCancel, GestureTapDownCallback? onDoubleTapDown, GestureTapCallback? onDoubleTap, GestureTapCancelCallback? onDoubleTapCancel, GestureLongPressDownCallback? onLongPressDown, GestureLongPressCancelCallback? onLongPressCancel, GestureLongPressCallback? onLongPress, GestureLongPressStartCallback? onLongPressStart, GestureLongPressMoveUpdateCallback? onLongPressMoveUpdate, GestureLongPressUpCallback? onLongPressUp, GestureLongPressEndCallback? onLongPressEnd, GestureLongPressDownCallback? onSecondaryLongPressDown, GestureLongPressCancelCallback? onSecondaryLongPressCancel, GestureLongPressCallback? onSecondaryLongPress, GestureLongPressStartCallback? onSecondaryLongPressStart, GestureLongPressMoveUpdateCallback? onSecondaryLongPressMoveUpdate, GestureLongPressUpCallback? onSecondaryLongPressUp, GestureLongPressEndCallback? onSecondaryLongPressEnd, GestureLongPressDownCallback? onTertiaryLongPressDown, GestureLongPressCancelCallback? onTertiaryLongPressCancel, GestureLongPressCallback? onTertiaryLongPress, GestureLongPressStartCallback? onTertiaryLongPressStart, GestureLongPressMoveUpdateCallback? onTertiaryLongPressMoveUpdate, GestureLongPressUpCallback? onTertiaryLongPressUp, GestureLongPressEndCallback? onTertiaryLongPressEnd, GestureDragDownCallback? onVerticalDragDown, GestureDragStartCallback? onVerticalDragStart, GestureDragUpdateCallback? onVerticalDragUpdate, GestureDragEndCallback? onVerticalDragEnd, GestureDragCancelCallback? onVerticalDragCancel, GestureDragDownCallback? onHorizontalDragDown, GestureDragStartCallback? onHorizontalDragStart, GestureDragUpdateCallback? onHorizontalDragUpdate, GestureDragEndCallback? onHorizontalDragEnd, GestureDragCancelCallback? onHorizontalDragCancel, GestureForcePressStartCallback? onForcePressStart, GestureForcePressPeakCallback? onForcePressPeak, GestureForcePressUpdateCallback? onForcePressUpdate, GestureForcePressEndCallback? onForcePressEnd, GestureDragDownCallback? onPanDown, GestureDragStartCallback? onPanStart, GestureDragUpdateCallback? onPanUpdate, GestureDragEndCallback? onPanEnd, GestureDragCancelCallback? onPanCancel, GestureScaleStartCallback? onScaleStart, GestureScaleUpdateCallback? onScaleUpdate, GestureScaleEndCallback? onScaleEnd, HitTestBehavior? behavior, bool excludeFromSemantics = false, DragStartBehavior dragStartBehavior = DragStartBehavior.start, Set<PointerDeviceKind>? supportedDevices})
Creates a widget that detects gestures.

Properties

behavior HitTestBehavior?
How this gesture detector should behave during hit testing.
final
child Widget?
The widget below this widget in the tree.
final
dragStartBehavior DragStartBehavior
Determines the way that drag start behavior is handled.
final
excludeFromSemantics bool
Whether to exclude these gestures from the semantics tree. For example, the long-press gesture for showing a tooltip is excluded because the tooltip itself is included in the semantics tree directly and so having a gesture to show it would result in duplication of information.
final
hashCode int
The hash code for this object.
nonVirtual">@nonVirtualread-onlyinherited
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
onDoubleTap GestureTapCallback?
The user has tapped the screen with a primary button at the same location twice in quick succession.
final
onDoubleTapCancel GestureTapCancelCallback?
The pointer that previously triggered onDoubleTapDown will not end up causing a double tap.
final
onDoubleTapDown GestureTapDownCallback?
A pointer that might cause a double tap has contacted the screen at a particular location.
final
onForcePressEnd GestureForcePressEndCallback?
The pointer is no longer in contact with the screen.
final
onForcePressPeak GestureForcePressPeakCallback?
The pointer is in contact with the screen and has pressed with the maximum force. The amount of force is at least ForcePressGestureRecognizer.peakPressure.
final
onForcePressStart GestureForcePressStartCallback?
The pointer is in contact with the screen and has pressed with sufficient force to initiate a force press. The amount of force is at least ForcePressGestureRecognizer.startPressure.
final
onForcePressUpdate GestureForcePressUpdateCallback?
A pointer is in contact with the screen, has previously passed the ForcePressGestureRecognizer.startPressure and is either moving on the plane of the screen, pressing the screen with varying forces or both simultaneously.
final
onHorizontalDragCancel GestureDragCancelCallback?
The pointer that previously triggered onHorizontalDragDown did not complete.
final
onHorizontalDragDown GestureDragDownCallback?
A pointer has contacted the screen with a primary button and might begin to move horizontally.
final
onHorizontalDragEnd GestureDragEndCallback?
A pointer that was previously in contact with the screen with a primary button and moving horizontally is no longer in contact with the screen and was moving at a specific velocity when it stopped contacting the screen.
final
onHorizontalDragStart GestureDragStartCallback?
A pointer has contacted the screen with a primary button and has begun to move horizontally.
final
onHorizontalDragUpdate GestureDragUpdateCallback?
A pointer that is in contact with the screen with a primary button and moving horizontally has moved in the horizontal direction.
final
onLongPress GestureLongPressCallback?
Called when a long press gesture with a primary button has been recognized.
final
onLongPressCancel GestureLongPressCancelCallback?
A pointer that previously triggered onLongPressDown will not end up causing a long-press.
final
onLongPressDown GestureLongPressDownCallback?
The pointer has contacted the screen with a primary button, which might be the start of a long-press.
final
onLongPressEnd GestureLongPressEndCallback?
A pointer that has triggered a long-press with a primary button has stopped contacting the screen.
final
onLongPressMoveUpdate GestureLongPressMoveUpdateCallback?
A pointer has been drag-moved after a long-press with a primary button.
final
onLongPressStart GestureLongPressStartCallback?
Called when a long press gesture with a primary button has been recognized.
final
onLongPressUp GestureLongPressUpCallback?
A pointer that has triggered a long-press with a primary button has stopped contacting the screen.
final
onPanCancel GestureDragCancelCallback?
The pointer that previously triggered onPanDown did not complete.
final
onPanDown GestureDragDownCallback?
A pointer has contacted the screen with a primary button and might begin to move.
final
onPanEnd GestureDragEndCallback?
A pointer that was previously in contact with the screen with a primary button and moving is no longer in contact with the screen and was moving at a specific velocity when it stopped contacting the screen.
final
onPanStart GestureDragStartCallback?
A pointer has contacted the screen with a primary button and has begun to move.
final
onPanUpdate GestureDragUpdateCallback?
A pointer that is in contact with the screen with a primary button and moving has moved again.
final
onScaleEnd GestureScaleEndCallback?
The pointers are no longer in contact with the screen.
final
onScaleStart GestureScaleStartCallback?
The pointers in contact with the screen have established a focal point and initial scale of 1.0.
final
onScaleUpdate GestureScaleUpdateCallback?
The pointers in contact with the screen have indicated a new focal point and/or scale.
final
onSecondaryLongPress GestureLongPressCallback?
Called when a long press gesture with a secondary button has been recognized.
final
onSecondaryLongPressCancel GestureLongPressCancelCallback?
A pointer that previously triggered onSecondaryLongPressDown will not end up causing a long-press.
final
onSecondaryLongPressDown GestureLongPressDownCallback?
The pointer has contacted the screen with a secondary button, which might be the start of a long-press.
final
onSecondaryLongPressEnd GestureLongPressEndCallback?
A pointer that has triggered a long-press with a secondary button has stopped contacting the screen.
final
onSecondaryLongPressMoveUpdate GestureLongPressMoveUpdateCallback?
A pointer has been drag-moved after a long press with a secondary button.
final
onSecondaryLongPressStart GestureLongPressStartCallback?
Called when a long press gesture with a secondary button has been recognized.
final
onSecondaryLongPressUp GestureLongPressUpCallback?
A pointer that has triggered a long-press with a secondary button has stopped contacting the screen.
final
onSecondaryTap GestureTapCallback?
A tap with a secondary button has occurred.
final
onSecondaryTapCancel GestureTapCancelCallback?
The pointer that previously triggered onSecondaryTapDown will not end up causing a tap.
final
onSecondaryTapDown GestureTapDownCallback?
A pointer that might cause a tap with a secondary button has contacted the screen at a particular location.
final
onSecondaryTapUp GestureTapUpCallback?
A pointer that will trigger a tap with a secondary button has stopped contacting the screen at a particular location.
final
onTap GestureTapCallback?
A tap with a primary button has occurred.
final
onTapCancel GestureTapCancelCallback?
The pointer that previously triggered onTapDown will not end up causing a tap.
final
onTapDown GestureTapDownCallback?
A pointer that might cause a tap with a primary button has contacted the screen at a particular location.
final
onTapUp GestureTapUpCallback?
A pointer that will trigger a tap with a primary button has stopped contacting the screen at a particular location.
final
onTertiaryLongPress GestureLongPressCallback?
Called when a long press gesture with a tertiary button has been recognized.
final
onTertiaryLongPressCancel GestureLongPressCancelCallback?
A pointer that previously triggered onTertiaryLongPressDown will not end up causing a long-press.
final
onTertiaryLongPressDown GestureLongPressDownCallback?
The pointer has contacted the screen with a tertiary button, which might be the start of a long-press.
final
onTertiaryLongPressEnd GestureLongPressEndCallback?
A pointer that has triggered a long-press with a tertiary button has stopped contacting the screen.
final
onTertiaryLongPressMoveUpdate GestureLongPressMoveUpdateCallback?
A pointer has been drag-moved after a long press with a tertiary button.
final
onTertiaryLongPressStart GestureLongPressStartCallback?
Called when a long press gesture with a tertiary button has been recognized.
final
onTertiaryLongPressUp GestureLongPressUpCallback?
A pointer that has triggered a long-press with a tertiary button has stopped contacting the screen.
final
onTertiaryTapCancel GestureTapCancelCallback?
The pointer that previously triggered onTertiaryTapDown will not end up causing a tap.
final
onTertiaryTapDown GestureTapDownCallback?
A pointer that might cause a tap with a tertiary button has contacted the screen at a particular location.
final
onTertiaryTapUp GestureTapUpCallback?
A pointer that will trigger a tap with a tertiary button has stopped contacting the screen at a particular location.
final
onVerticalDragCancel GestureDragCancelCallback?
The pointer that previously triggered onVerticalDragDown did not complete.
final
onVerticalDragDown GestureDragDownCallback?
A pointer has contacted the screen with a primary button and might begin to move vertically.
final
onVerticalDragEnd GestureDragEndCallback?
A pointer that was previously in contact with the screen with a primary button and moving vertically is no longer in contact with the screen and was moving at a specific velocity when it stopped contacting the screen.
final
onVerticalDragStart GestureDragStartCallback?
A pointer has contacted the screen with a primary button and has begun to move vertically.
final
onVerticalDragUpdate GestureDragUpdateCallback?
A pointer that is in contact with the screen with a primary button and moving vertically has moved in the vertical direction.
final
runtimeType Type
A representation of the runtime type of the object.
read-onlyinherited
supportedDevices Set<PointerDeviceKind>?
The kind of devices that are allowed to be recognized.
final

Methods

build(BuildContext context) Widget
Describes the part of the user interface represented by this widget.
override
createElement() StatelessElement
Creates a StatelessElement to manage this widget's location in the tree.
inherited
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
protected">@protectedinherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
override
noSuchMethod(Invocation invocation) → dynamic
Invoked when a non-existent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a one-line detailed description of the object.
inherited
toStringShort() String
A short, textual description of this widget.
inherited

Operators

operator ==(Object other) bool
The equality operator.
nonVirtual">@nonVirtualinherited