Flutter does provide common widgets handling tap, such as IconButton. But sometimes, you need to detect gestures on a custom view: here comes GestureDetector!
How to add a GestureDetector
To follow the code tutorial, create a new app as follows.
1 |
flutter create gesturedetectorexample |
If you’re unsure how to set up a Flutter app, check out Getting started with Flutter official tutorial.
In main.dart, we launch the app as below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import 'package:flutter/material.dart'; import 'home/home_view.dart'; void main() { runApp(new MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return new MaterialApp( title: 'GestureDetector Example', theme: new ThemeData( primaryColor: const Color(0xFF43a047), accentColor: const Color(0xFFffcc00), primaryColorBrightness: Brightness.dark, ), home: new HomePage(), ); } } |
This won’t build until we create HomePage. So let’s create a new folder home in lib folder, and add the file home_view.dart to it. Let’s add some UI code, to display a line of text, an icon, and another line of text, all of it with a red background.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
import 'package:flutter/material.dart'; class HomePage extends StatefulWidget { HomePage({Key key}) : super(key: key); @override _HomePageState createState() => new _HomePageState(); } class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { Widget redSection = new Container( color: Colors.red, child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: [ new Text("Launch Search"), new IconButton( icon: new Icon(Icons.search), onPressed: null, ), new Text( "Tapping this text, the icon, or the title, will launch search"), ], ), ); return new Scaffold( appBar: new AppBar( title: new Text("Gesture Detector Example"), ), body: new Padding( padding: new EdgeInsets.symmetric(vertical: 0.0, horizontal: 4.0), child: redSection, ), ); } } |
We assume now that we want the whole red section to be clickable, so let’s add a GestureDetector.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Widget redSection = new GestureDetector( child: new Container( color: Colors.red, child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: [ new Text("Launch Search"), new IconButton( icon: new Icon(Icons.search), onPressed: null, ), new Text( "Tapping this text, the icon, or the title, will launch search"), ], ), ), ); |
Display touch feedback when tapping a GestureDetector
The GestureDetector offers different handles for each touch state. To show visual feedback when the user taps the view, we are going to render the background of the GestureDetector’s child based on the touch state. We will use a boolean to track whether a tap gesture is in progress.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
class _HomePageState extends State<HomePage> { bool _tapInProgress; _HomePageState() { _tapInProgress = false; } void _tapDown(TapDownDetails details) { setState(() { _tapInProgress = true; }); } void _tapUp(TapUpDetails details) { setState(() { _tapInProgress = false; }); } void _tapCancel() { setState(() { _tapInProgress = false; }); } void _onTap() { // TODO - actual code you want to run once a tap happens } @override Widget build(BuildContext context) { Widget redSection = new GestureDetector( onTapDown: _tapDown, onTapUp: _tapUp, onTap: _onTap, onTapCancel: _tapCancel, child: new Container( color: _tapInProgress? Colors.redAccent:Colors.red, child: new Column( mainAxisAlignment: MainAxisAlignment.center, children: [ new Text("Launch Search"), new IconButton( icon: new Icon(Icons.search), onPressed: null, ), new Text( "Tapping this text, the icon, or the title, will launch search"), ], ), ), ); return new Scaffold( appBar: new AppBar( title: new Text("Gesture Detector Example"), ), body: new Padding( padding: new EdgeInsets.symmetric(vertical: 0.0, horizontal: 4.0), child: redSection, ), ); } } |
Voila! We are now handling touch, and displaying touch feedback, when a user taps anywhere on the red section.
What next?
Check out the full list of currently supported gestures in Flutter.

Mobile app developer with 12 years experience. Started with the Android SDK in 2010 and switched to Flutter in 2017. Past apps range from start ups to large tech (Google) and non tech (British Airways) companies, in various sectors (transport, commercial operations, e-commerce).
Thank you again for taking the time to make and beautifully present this tutorial.