Adding touch interaction to your application enhance its user-friendliness and increase is usefulness. Flutter provides several ways to add touch-based interactions such as InkWell and GestureDetector. Both have many features in common and are used for very similar purposes. but they also got various differences that make each of them distinct from the other.
They both look the same and almost do the same thing, so what is difference between flutter InkWell vs GestureDetector?
Generally speaking, GestureDetector provides more gesture control to detect almost every user interaction including dragging, swiping, pinching, etc. On the other hand, InkWell has a limited number of gestures to detect but it provides more decoration control in addition to its ripple effect and its larger spot for gesture detection.
In this article, we’ll learn about InkWell and GestureDetector and the difference between both.
Table of Contents
InkWell
The InkWell is a rectangular area of a material class which responds to touch events with clipped splash effect. Now, what makes InkWell special is the visual feedback it gives when the user interacts with it. It is a must for the InkWell to have a Material widget as an ancestor in order to display the splash effect correctly. This material widget responsibility is for the ink reaction to be painted when the touch event occurs. When it’s tapped, the ink is spread in the rectangular area as a highlight. According to Flutter documentation, this is how it looks when tapped:

In addition, InkWell makes the whole area of the material parent widget as a hotspot which can help receive the user’s interaction easily. The InkWell responds to various gestures based on the action the user performs. Below is a table of the gestures that InkWell responds to:
onTap | called when the user taps the button a single time |
onDoubleTap | called when the user double taps this part of the material |
onLongPress | called when the user long presses this part of the material |
onTapDown | called when the user cancels a tap that was started on this part |
onTapCancel | called when the user taps down this part of the material |
Example
Ink(
child: InkWell(
splashColor: Colors.red,
highlightColor: Colors.yellow,
child: Container(
width: 200,
height: 100,
child: Text('Click Me', style: TextStyle(fontSize: 20),),
alignment: Alignment.center,
),
onTap: () {
setState(() {
text = 'tapped';
});
},
onDoubleTap: () {
setState(() {
text = 'double tapped';
});
},
onLongPress: (){
setState(() {
text = 'long pressed';
});
},
onTapDown: (value){setState(() {
text = 'tapped down';
});},
onTapCancel: () {
setState(() {
text = 'tap cancelled';
});
},
),
),
Output
Above is an example of how to implement InkWell and handle its different events. As an illustration, a Text field is displayed below the InkWell widget that displays the event being triggered.
[videopress IgwOrt34]
GestureDetector
Gesture detector is another widget to provide interactions in applications and it is used to, as its name suggests, detect gestures of the users. This is used when you want to provide interaction ability to widgets that don’t have a default built-in way to detect gestures such as containers and text widgets. These widgets are usually wrapped with a GestureDetector to detect gestures performed on them. In contrast with InkWell, GestureDetector doesn’t have a visual effect when the event occurs. In addition, GestureDetecor doesn’t make the whole area as a hotspot to detect gestures. If it has a child, then it depends on that child for its size behavior. If it doesn’t have a child, then it’ll grow to fit its parent size.
On the other hand, GestureDetectors provide a wider variety of gestures to be detected. Below is a table of the gestures a GestureDetector responds to:
1. Tap | onTap | called when the user taps the screen |
onTapUp | called when the user stops making contact with the screen | |
onTapDown | called when the user starts making contact the screen and it might be a tap | |
onTapCancel | called when the event that fired onTapDown is not a tap | |
2. Double Tap | onDoubleTap | called when the user quickly taps the screen twice at the same position |
onDoubleTapDown | called when the user touches the screen and it might be a double tap | |
onDoubleTapCancel | called when the even that fired onDoubleTapDown is not a double tap | |
3. Long Press | onLongPressDown | called when the user touches the screen and it might be a long press |
onLongPressStart | called when the start of a long press event is detected | |
onLongPress | called when a long press event is detected | |
onLongPressMoveUpdate | called when long press event is detected and the user drag-moves finger | |
onLongPressEnd | called when the end of a long press event is detected | |
onLongPressUp | called when the end of long press event is detect and the contact is removed | |
onLongPressCancel | called when the event that fired onLongPressDown is not a long press | |
4. Scale | onScaleStart | Called when contact with screen establishes a focal point and initial scale of 1.0 |
onScaleUpdate | called when the contact with the screen indicates a new focal point | |
onScaleEnd | called when the user stops making contact. | |
5. Vertical Drag | onVerticalDragDown | called when the user makes contact with the screen and there is a possibility of a vertical move |
onVerticalDragStart | called with user makes contacts the screen and begins to move vertically | |
onVerticalDragUpdate | called when the user moves again in a vertical direction | |
onVerticalDragEnd | called when the end of a vertical drag is detected | |
onVerticalDragCancel | called when the event that fired onVerticalDragDown is not a vertical drag | |
6. Horizontal Drag | onHorizontalDragDown | called when the user makes contact with the screen and there’s a possibility of a horizontal move |
onHorizontalDragStart | called when the user makes contact with the screen and starts to move horizontally | |
onHorizontalDragUpdate | called when the contact the user made is moving again in a horizontal direction | |
onHorizontalDragEnd | called when the end of a horizontal drag is detected | |
onHorizontalDragCancel | called when the even that fired onHorizontalDragDown is not a horizontal drag | |
Secondary/Tertiary Tap (usually for web applications) | onSecondaryTapDown /onTertiaryTapDown | called when the user makes contact with a secondary/tertiary button, might be a tap |
onSecondaryTapCancel /onTertiaryTapCancel | called when the event fired onSecondaryTapDown is not a tap | |
onSecondaryTap /onTertiaryTap | called when the user taps the screen with a secondary button | |
onSecondaryTapUp /onTertiaryTapUp | called when the user stops making contact with the screen | |
Secondary/Tertiary Long Press(For Web) | onSecondaryLongPressDown /onTertiaryLongPressDown | called when the user makes contact with the screen using secondary/tertiary button and it might be a long press |
onSecondaryLongPress /onTertiaryLongPress | called when the user long presses the screen with a secondary/tertiary button | |
onSecondaryLongPressStart /onTertiaryLongPressStart | called when the user makes contact with the screen using a secondary/tertiary button and starts a long press | |
onSecondaryLongPressMoveUpdate /onTertiaryLongPressMoveUpdate | called when long press event is detected and the user drag-moves finger using a secondary/tertiary button | |
onSecondaryLongPressEnd /onTertiaryLongPressEnd | called when the use stops making contact with the screen using the secondary/tertiary button | |
onSecondaryLongPressUp /onTertiaryLongPressUp | called when the user stops making contact with the screen using the secondary/tertiary button | |
onSecondaryLongPressCancel /onTertiaryLongPressCancel | called when the event that triggered onSecondaryLongPressDown/ onTertiaryLongPressDown is not a long press | |
Example
In this example, I will demostrate how to implement some of the GestureDetector events in a very simple way
GestureDetector(
child: Icon(Icons.favorite, size: 50,),
onTap: () {
setState(() {
text = 'Tapped';
});
},
onLongPress: () {
setState(() {
text = 'Long Pressed';
});
},
onHorizontalDragStart: (value) {
setState(() {
text = 'Horizontally dragged';
});
},
onVerticalDragStart: (value) {
setState(() {
text = 'vertically dragged';
});
},
),
Output

Conclusion
As can be seen from our discussion above, both InkWell and GestureDetector widgets provide the functionality to detect the user’s interaction with the screen but also have their major differences. In brief, InkWell provide more visual response while Gesture detector provide more events (gestures) to capture from the user’s interaction.
Now that you understand the differences between the two widgets you can start using them more wisely in their correct places and for the right purposes. I hope you enjoyed this tutorial and learnt from it.
Don’t forget to share this post with your friends who are interested in learning more about Flutter Widgets.