129

I have this container:

  new Container(
    width: 500.0,
    padding: new EdgeInsets.fromLTRB(20.0, 40.0, 20.0, 40.0),
    color: Colors.green,
    child: new Column(
      children: [
        new Text("Ableitungen"),
      ]
    ),
  ),

When the user clicks on the Container, I want an onPressed() method to be fired (like it can be done with IconButton for example). How can I achieve this behaviour with Container?

CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
OhMad
  • 6,871
  • 20
  • 56
  • 85

11 Answers11

251

You can use a GestureDetector widget like this:

new GestureDetector(
        onTap: (){
          print("Container clicked");
        },
        child: new Container(
          width: 500.0,
          padding: new EdgeInsets.fromLTRB(20.0, 40.0, 20.0, 40.0),
          color: Colors.green,
          child: new Column(
              children: [
                new Text("Ableitungen"),
              ]
          ),
        )
    );
guest3523
  • 2,740
  • 2
  • 14
  • 7
  • I want to add on tap functionality to container .... have tried both inkwell and gesture detector as well but both are not working !!! – Ali Yar Khan Jun 07 '21 at 06:03
151

Don't use GestureDetector, it doesn't show ripple effect. Use InkWell instead.

InkWell(
  onTap: () {}, // Handle your callback
  child: Ink(height: 100, width: 100, color: Colors.blue),
)

Output:

enter image description here

CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
  • 5
    FYI: If you use Container inside the InkWell then ripple may not appear if you also have the `decoration`. See https://stackoverflow.com/questions/51463515/inkwell-not-showing-ripple-when-used-with-container-decoration. As shown by @CopsOnRoad use Ink, it supports almost all features as Container. – Nikhil Wagh Jan 02 '21 at 17:08
  • I want to add on tap functionality to container .... have tried both inkwell and gesture detector as well but both are not working !!! – Ali Yar Khan Jun 07 '21 at 06:04
  • ripple is not shown for me using container + decration – Kristi Jorgji Oct 20 '22 at 14:16
  • @KristiJorgji Yes, that's why you should use `Ink` and not a `Container`. However, you can set a color with some opacity in your container to see the ripple effect but it's more of a workaround and may not always fit your needs. So, better to use `Ink` as shown above. – CopsOnRoad Oct 20 '22 at 15:24
21

The simplest solution is to wrap the Container in a GestureRecognizer, but consider using an InkWell or FlatButton if you are building a Material design app. These widgets will show a visual splash response when touched.

Collin Jackson
  • 110,240
  • 31
  • 221
  • 152
14

The container itself doesn't have any click event, so to do that there are two ways

  1. InkWell widget
  2. GestureDetector

In Flutter, InkWell is a material widget that responds to touch action.

InkWell(
    child: Container(......),
    onTap: () { 
        print("Click event on Container"); 
    },
);

GestureDetector is a widget that detects the gestures.

GestureDetector(
    onTap: () { 
        print("Click event on Container"); 
    },
    child: Container(.......),
)

Difference

InkWell is a material widget and it can show you a Ripple Effect whenever a touch was received.

GestureDetector is more general-purpose, not only for touch but also for other gestures.

Jitesh Mohite
  • 31,138
  • 12
  • 157
  • 147
5

Heading

GestureDetector vs InkWell

You can use two widget

1) GestureDetector

    GestureDetector(

        onTap: (){
          print("Container clicked");
        },
        child: new Container(child: ...)          
    );

This widget, doesn't have any effect.

2) InkWell

    InkWell(

        child: Container(......),
        onTap: () { 
            print("Click event on Container"); 
        },
    );

This widget has animation effect.

Shivam Kumar
  • 1,892
  • 2
  • 21
  • 33
4

Just wanted to add on to The Dumbfounds answer(accepted ans above)

If you are using GestureDetector or InkWell to handle the click of a group of icon and text, then use Icon widget instead of IconButton to display the icon as the onPressed method of IconButton will take over the onTap method of GestureDetector/InkWell and as a result the onTap then will only work if you click on the text.

Example -

@override
  Widget build(BuildContext context) {
    return Row(mainAxisSize: MainAxisSize.min, children: [
      GestureDetector(
        onTap: () {
          _toggleFavorite();
        },
        child: Row(
          children: [
            Container(
              padding: EdgeInsets.all(0.0),
              child: _isFavorited ? Icon(Icons.star, color: Colors.red[500]) : Icon(Icons.star_border),
            ),
            SizedBox(
              width: 18.0,
              child: Container(
                child: Text('$_favoriteCount'),
              ),
            )
          ],
        ),
      )
    ]);
  }
}
Annsh Singh
  • 435
  • 5
  • 12
2
InkWell(
    child: Container(
    width: 500.0,
    padding: new EdgeInsets.fromLTRB(20.0, 40.0, 20.0, 40.0),
    color: Colors.green,
    child: new Column(
        children: [
            new Text("Ableitungen"),
            ]
        ),
    ),
    onTap: () { 
        print("Tapped on container"); 
    },
);
Chanaka N. Bandara
  • 247
  • 1
  • 3
  • 10
1

User can make button of any widget using Inkwell and GestureDetector.

InkWell(
    onTap: () { 
        print("Tapped"); 
    },
    child: Container(/* ... */),
);
GestureDetector(
    onTap: () { 
        print("Tapped"); 
    },
    child: Container(/* ... */),
)
user16217248
  • 3,119
  • 19
  • 19
  • 37
0

Use GestureDetector to give ontap on Container. Wrap Container with GestureDetector Widget:

GestureDetector(
    onTap: () { 
        print("Please tap here."); 
    },
    child: Container(
        width: 500.0,
        padding: new EdgeInsets.fromLTRB(20.0, 40.0, 20.0, 40.0),
        color: Colors.green,
        child: new Column(
          children: [
            new Text("Hello"),
          ]
        ),
    ),
),
user16217248
  • 3,119
  • 19
  • 19
  • 37
0

Actual Answer of the question

InkWell is the best from user experience.

 Container(            
        child: InkWell(
          onTap: () { //handle your callback   },
          child: Ink(
            color: Colors.amber,
            child: Padding(
                  padding: EdgeInsets.all(16.0),
                  child: Text('Click on me'),
            ),                  
          ),
        ),
      );
infomasud
  • 2,263
  • 1
  • 18
  • 12
-1
InkWell(
    child: Container(/* ... */),
    onTap: () { 
        print("Add your on tap event in this block"); 
    },
);

Use InkWell because it will provide you a nice material ripple effect.

user16217248
  • 3,119
  • 19
  • 19
  • 37