Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter - How tap / touch area works?

1) If I have this, when I tap the child Container it doesn't print 'tap':

Container(
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container(
      width: 100,
      height: 100,
    ),
  ),
),

2) If I have this, when I tap the child Container it prints 'tap':

Container(
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container(
      width: 100,
      height: 100,
      decoration: BoxDecoration(),
    ),
  ),
),

3) If I have this, when I tap the child Container, outside the text, it prints 'tap':

Container(
  color: Colors.red,
  child: GestureDetector(
    onTap: () => print('tap'),
    child: Container(
      width: 100,
      height: 100,
      child: Text("A"),
    ),
  ),
),

Can someone explain me these 3 behaviors?

like image 894
Pablo Barrera Avatar asked Jun 12 '26 15:06

Pablo Barrera


1 Answers

  1. A Container with bounds (height and width) is nothing but a placeholder for other widgets to go inside it. Since you haven't provided any child to it or any other property such as color or decoration to it, the container is considered to be invisible for GestureDetector.

According to the official GestureDetector document, by default a GestureDetector with an invisible child ignores touches. this behavior can be controlled with behavior.

If you still want the placeholder container to be recognized as tap event, use behavior property of GestureDetector, that will tell GestureDetector to tap on the container and then you will see tap printed, as below:

Container(
          color: Colors.red,
          child: GestureDetector(
            behavior: HitTestBehavior.opaque,
            onTap: () => print('tap'),
            child: Container(
              width: 100,
              height: 100,
            ),
          ),
        ),
  1. In this case, since you provided decoration property and used BoxDecoration(), it renders a box based on the bounds provided by its parent widget. So, the container has a box shape. In order to see how the box shape is rendered inside the container, just provide a border property, as below:
Container(
        color: Colors.red,
        child: GestureDetector(
          onTap: () => print('tap'),
          child: Container(
            width: 100,
            height: 100,
            decoration: BoxDecoration(
              border: Border.all(color: Colors.yellow, width: 4)
            ),
          ),

enter image description here

You can see the yellow borders spanning entire container size, which acts as a layer on top of the container and now considered to be tappable. Hence, GestureDetector's tap is recognized and you see tap printed.

  1. In this case, since you have provided child widget as text, GestureDetector identifies it since the widget is visible and hence tap is printed, irrespective of whether you tap on the text or outside of it, because since GestureDetector doesn't have a size by itself, it relies on child's size, which in this case is the bounds (height and width). Hence, it considers the entire bounded area to be tappable and you get the tap event printed anywhere inside it.

Hope this answers your question.

like image 153
Darshan Avatar answered Jun 15 '26 07:06

Darshan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!