Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to add GestureDector to Listview.builder card in Flutter?

I have an Expanded widget wrapped around a Listview.builder of Card. How can I make my card not only detect onTap but also pass variables to my new .dart file on Navigation. I'm currently getting a sizing error?

Updated With Code

Here is my code:

new Expanded(
                child: new ListView.builder(
                    itemCount: id == null ? 0 : id.length,
                    itemBuilder: (BuildContext context, int index) {
                      return new Card(
                        child: new Column(
                          children: <Widget>[
                            new Image.network(video[index]),
                            new Padding(padding: new EdgeInsets.all(3.0)),
                            new Text(title[index],
                            style: new TextStyle(fontWeight: FontWeight.bold,
                            color: Colors.black),
                            ),
                            new GestureDetector(onTap: (){
                              print(id[index]);
                            },)

                          ],
                        ),
                      );

                    }))

Here is the thrown exception:

The following assertion was thrown during performLayout():
RenderPointerListener object was given an infinite size during layout.
This probably means that it is a render object that tries to be as big as possible, but it was put
inside another render object that allows its children to pick their own size.

I would like to pass title[index] and video[index] similar to didSelectRowAtIndexPath in iOS Swift.

like image 631
Charles Jr Avatar asked Sep 26 '17 00:09

Charles Jr


People also ask

How do you add GestureDetector in Flutter?

In BuildContext() we return Scaffold() and use the property of AppBar() and pass the title of the application. In the body of Scaffold(), we pass Center() and after that, we pass GestureDetector() as a child of it. We create a Container() and pass the color and text which is already passed the code.

Can I use expanded in ListView Flutter?

1. Using Expanded (Recommended) You can wrap your ListView widget inside the Expanded widget and this will allow the ListView to take all the available as long as the Column allows.

How do I use ListView separated in Flutter?

This constructor is ListView.ListView. separated creates a fixed-length, scrollable , linear array of list “items” separated by list item “separators”. The itemBuilder callback is called whenever there are indices ≥ 0 and< itemCount .


2 Answers

You are adding the GestureDetector as one child of the Column, and Flutter does not understand what piece of UI this GestureDetector needs to be detecting different touch events on (you are not specifying where exactly do you need this GestureDetector to be performing its task)

If you need the whole Card to be interactive, you need to wrap your Card within a GestureDecetor as follows

var id = ["title 1", "title 2", "title 3", "title 4", "title 5",];

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new ListView.builder(
          itemCount: id == null ? 0 : id.length,
          itemBuilder: (BuildContext context, int index) {
            return new GestureDetector( //You need to make my child interactive
              onTap: () => print(id[index]),
              child: new Card( //I am the clickable child
                child: new Column(
                  children: <Widget>[
                    //new Image.network(video[index]),
                    new Padding(padding: new EdgeInsets.all(3.0)),
                    new Text(id[index],
                      style: new TextStyle(fontWeight: FontWeight.bold,
                          color: Colors.black),
                    ),


                  ],
                ),),
            );
          }),
    );
  }
like image 190
Shady Aziza Avatar answered Sep 28 '22 02:09

Shady Aziza


Similar to aziza's suggestion you could have a look at InkWell which basically is a GestureDetector but has the material design splash.

You also asked about how to pass variables to another class. You can do that by just handing them over in your instantiation as constructor variables. Have a look at the onTap method in the code example.

Code could look like this:

@override
Widget build(BuildContext context) {
  return new Scaffold(
    body: new ListView.builder(
      itemCount: id == null ? 0 : id.length,
      itemBuilder: (BuildContext context, int index) {
        return new InkWell(
          onTap: () {
            Navigator.push(
              context,
              new MaterialPageRoute(
                builder: (context) {
                  return new OtherClass(id[index], video[index]);
                },
              ),
            );
          },
          child: new Card(
            child: new Column(
              children: <Widget>[
                //new Image.network(video[index]),
                new Padding(padding: new EdgeInsets.all(3.0)),
                new Text(id[index],
                  style: new TextStyle(fontWeight: FontWeight.bold,
                      color: Colors.black
                  ),
                ),
              ],
            ),
          ),
        );
      }),
  );
}

*Code not tested

like image 20
Rainer Wittmann Avatar answered Sep 28 '22 04:09

Rainer Wittmann