Ahmet Balaman LogoAhmet Balaman

Flutter: GestureDetector Usage and Touch Events

personAhmet Balaman
calendar_today
FlutterGestureDetectorTouchGestureWidgetUI

GestureDetector is a powerful widget that allows us to add touch events like tap, double tap, long press, and swipe to any widget. It makes normally non-clickable widgets interactive.

Live Demo

You can try this widget in the interactive example below:

💡 If the example above doesn't load, click DartPad to run it in a new tab.

Basic Usage

You can make any widget tappable with GestureDetector:

GestureDetector(
  onTap: () {
    print('Tapped!');
  },
  child: Container(
    padding: EdgeInsets.all(20),
    color: Colors.blue,
    child: Text('Tap me'),
  ),
)

Supported Gesture Types

Tap Events

GestureDetector(
  onTap: () => print('Single tap'),
  onDoubleTap: () => print('Double tap'),
  onLongPress: () => print('Long press'),
  onTapDown: (details) => print('Finger touched'),
  onTapUp: (details) => print('Finger lifted'),
  onTapCancel: () => print('Tap cancelled'),
  child: MyWidget(),
)

Drag Events

GestureDetector(
  // Horizontal drag
  onHorizontalDragStart: (details) => print('Horizontal drag started'),
  onHorizontalDragUpdate: (details) => print('Delta: ${details.delta.dx}'),
  onHorizontalDragEnd: (details) => print('Velocity: ${details.primaryVelocity}'),
  
  // Vertical drag
  onVerticalDragStart: (details) => print('Vertical drag started'),
  onVerticalDragUpdate: (details) => print('Delta: ${details.delta.dy}'),
  onVerticalDragEnd: (details) => print('Velocity: ${details.primaryVelocity}'),
  
  // Pan (any direction)
  onPanStart: (details) => print('Pan started'),
  onPanUpdate: (details) => print('Position: ${details.localPosition}'),
  onPanEnd: (details) => print('Pan ended'),
  
  child: MyWidget(),
)

Scale (Pinch) Events

GestureDetector(
  onScaleStart: (details) => print('Scale started'),
  onScaleUpdate: (details) {
    print('Scale: ${details.scale}');
    print('Rotation: ${details.rotation}');
  },
  onScaleEnd: (details) => print('Scale ended'),
  child: MyWidget(),
)

InkWell Alternative

If you want Material Design ripple effect, you can use InkWell:

InkWell(
  onTap: () => print('Tapped'),
  onLongPress: () => print('Long pressed'),
  splashColor: Colors.orange.withOpacity(0.3),
  highlightColor: Colors.orange.withOpacity(0.1),
  borderRadius: BorderRadius.circular(8),
  child: Container(
    padding: EdgeInsets.all(16),
    child: Text('Button with Ripple Effect'),
  ),
)

HitTestBehavior

Controls how touch events are detected:

GestureDetector(
  behavior: HitTestBehavior.opaque, // Detect on empty areas too
  // behavior: HitTestBehavior.translucent, // Pass to widgets below
  // behavior: HitTestBehavior.deferToChild, // Only detect on child (default)
  onTap: () => print('Tapped'),
  child: Container(
    width: 200,
    height: 200,
    // no color, transparent
    child: Center(child: Text('Tap')),
  ),
)

Summary

Event Description
onTap Single tap
onDoubleTap Double tap
onLongPress Long press
onHorizontalDrag* Horizontal drag
onVerticalDrag* Vertical drag
onPan* Any direction drag
onScale* Pinch zoom/rotate

GestureDetector is the most fundamental way to capture user interactions in Flutter.

Comments