GestureDetector: Making Any Widget Interactive
GestureDetector is an invisible wrapper that makes any widget interactive. Use it to add an `onTap` to a `Container` or custom widget. The biggest footgun: when nested, only the innermost detector's callback for a given gesture will fire.
WHY IT EXISTS Flutter needs a way to add interactivity to widgets that aren't inherently tappable, like a Container or Column. While buttons have built-in handlers, you often need to make a custom component or a whole section of the screen respond to a tap or swipe. GestureDetector solves this by providing a generic way to listen for user gestures on any widget.
THE MENTAL MODEL Think of GestureDetector as an invisible, stretchable glove you wrap around another widget. The glove itself has no appearance, but it's covered in sensors for taps, drags, and pinches. When a user interacts with the widget inside, the glove's sensors fire, triggering the callbacks you've defined. It doesn't change its child's appearance or layout; it just listens for events within its bounds.
HOW IT WORKS You wrap your target widget (e.g., a Card) with a GestureDetector and provide callback functions for the gestures you care about, like onTap, onDoubleTap, or onVerticalDragUpdate. When the user performs that gesture on the widget's area, Flutter's gesture system invokes your callback. If the GestureDetector has no child, it expands to fill its parent, making that entire area interactive. By default, it ignores touches on transparent areas, but this can be changed with the behavior property to HitTestBehavior.opaque or HitTestBehavior.translucent.
WHEN TO USE IT Use GestureDetector when you need to add gesture handling to a widget that doesn't have it built-in. This is perfect for making custom components interactive, such as making an entire Card with a Column of text tappable, detecting a swipe on an image carousel, or handling a pan gesture on a custom map widget. It is the standard tool for custom, non-Material gesture interactions.
WHEN NOT TO USE IT For standard Material Design components, prefer InkWell or InkResponse. These widgets provide the same tap detection but also include the visual "ink splash" ripple effect that users expect. Using GestureDetector for a button-like element means you must implement all visual feedback yourself. For very low-level pointer tracking (like for a drawing app), the Listener widget is more appropriate as it provides raw pointer data before it's interpreted as a gesture.
ONE CANONICAL EXAMPLE The most common footgun involves nested GestureDetectors. Imagine a large Container wrapped in a GestureDetector with an onTap. Inside it, a smaller Container is also wrapped in a GestureDetector with its own onTap. If you tap the inner Container, only its onTap callback will fire. The outer detector's onTap is ignored because the inner detector "wins" the right to handle the event in what Flutter calls the "gesture arena." The parent detector never receives the tap gesture.
Read the original → api.flutter.dev
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.