Search code examples
listviewflutterdartsetstate

Use setState in ListView


I trying to get data from two tables and display to ListView.

 child: Container(
                  child: StreamBuilder<List<ABC>>(
                      stream: _abcBloc
                          .getListStream,
                      builder: (context, snapshot) {
                        switch (snapshot.connectionState) {
                          case ConnectionState.waiting:
                            return Center(
                              child: Image.asset(
                                'assets/loading.gif',
                                width: 200.0,
                                height: 200.0,
                              ),
                            );
                            break;

                          case ConnectionState.active:
                            if (snapshot.data.isEmpty) {
                              return Container(child: Text('empty'));
                            } else {
                              return ListView.builder(
                                  shrinkWrap: true,
                                  itemCount: snapshot.data.length,
                                  itemBuilder: (context, index) {
                                    var _reading = snapshot.data[index];
                                    var name;

                                    _abcBloc.getName(_reading.Id)
                                        .then((onValue) {
                                      name = onValue.name;
                                    });

                                    return InkWell(
                                        onTap: () {},
                                        child: Padding(
                                          padding: EdgeInsets.all(10),
                                          child: Column(
                                            children: <Widget>[
                                              Text(name == null ? '' : name),
                                            ],
                                          ),
                                        ));
                                  });
                            }
                            break;

                          default:
                            return Text("edwqd");
                        }
                      }))

Firstly it will call _abcBloc.getListStream. I was able to get the data in this line (var _reading = snapshot.data[index];).

After that I want to get the name from another table by calling this function _abcBloc.getName(_reading.Id). However, the name is always show empty.


Solution

  • Whenever you are working with Future and creating widget based on value of your future, you should always use FutureBuilder.

    Replace your ListView.builder with following code:

    ListView.builder(
      shrinkWrap: true,
      itemCount: snapshot.data.length,
      itemBuilder: (context, index) {
      var _reading = snapshot.data[index];
      var name;
    
      // _abcBloc.getName(_reading.Id)
      //     .then((onValue) {
      //   name = onValue.name;
      // });
    
      return FutureBuilder(
        future: _abcBloc.getName(_reading.Id),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if(!snapshot.hasData) return Container();
          name = snapshot.data;
          return InkWell(
          onTap: () {},
          child: Padding(
            padding: EdgeInsets.all(10),
            child: Column(
              children: <Widget>[
                Text(name == null ? '' : name),
              ],
            ),
          ))
        },
      );
    });
    

    Hope this helps, in case of any doubts please comment. If it works for you don't forget to accept and up-vote the answer.