Search code examples
flutterlistviewdartbooleandart-pub

Update Flutter ListTile with tap not working


The goal is to change the values in the ListTile of leading and subtitle to null on tap. The tap is switching the _act boolean, but the ListTile's leading: and subtitle: values do not change from their initial state. My code for the ListView is below. Please help.

        return new ListView(
          children: querySnapShot.data.documents.map((DocumentSnapshot document) {
            bool _act = false;
            return new ListTile(
              leading: _act != false ? const Icon(Icons.remove_red_eye, color: Color(0xff00caff), size: 40) : null,
              title: new Text((DBProvider.db.idDeHasher(document['exampleid'], key) ?? 'fallback'), style: TextStyle(color: secondaryColor)),
              subtitle: _act != false ? new Text((document['exampleString']  ?? 'fallbackString'), style: TextStyle(color: secondaryColor)) : null,
              onTap: () { 
                _act = !_act;
                print(_act.toString());
                }
            );
          }).toList(),
        );

Solution

  • You need to make your widget a Stateful Widget and call setState when there is a tap on the ListTile.

    According to the docs:

    Calling setState notifies the framework that the internal state of this object has changed in a way that might impact the user interface in this subtree, which causes the framework to schedule a build for this State object.

    So if the state of the widget changes you have to call setState to trigger a rebuild of the view and see immediatly the changes implied by the new state.

    I added a demo using your code as an example:

         // define a list of acts
            List _acts = [];
             return new ListView(
              children: querySnapShot.data.documents.asMap().entries.map((entry) {
              // declare all entries of the list to false
              acts.add(false);
              // access the index 
              int index = entry.key;
              // access the document
              DocumentSnapshot document = entry.value;
              // DocumentSnapshot document = entry
                return new ListTile(
                  leading: _acts[index] != false ? const Icon(Icons.remove_red_eye, color: Color(0xff00caff), size: 40) : null,
                  title: new Text((DBProvider.db.idDeHasher(entry.val['exampleid'], key) ?? 'fallback'), style: TextStyle(color: secondaryColor)),
                  subtitle: _acts[index] != false ? new Text((document['exampleString']  ?? 'fallbackString'), style: TextStyle(color: secondaryColor)) : null,
                  onTap: () { 
                   // call setstate
                  setState(() { // new line
                  // change the bool variable based on the index
                   _acts[index] = !_acts[index];
                    print(_acts[index].toString());
                  });
                    }
                );
              }).toList(),
            );