简体   繁体   中英

Flutter: How to use StreamBuilder with ListView.separated

I want a ListView with items from a Stream. Of course, content of the List should reflect changes in the Stream. And due to my designer quirks, I want items in the List be separated by a divider.

Just wondering, what is the proper way to create a ListView with separators, and reacting on Stream changes.

body: StreamBuilder(
        stream: someStream,
        builder: (ctx, snapshot) {
          return ListView.separated(
            separatorBuilder: (context, index) => Divider(color: Colors.black),
            itemCount: ***whatsHere***?,
            itemBuilder: (BuildContext ctx, int index) {
...

Hope I've missed something. Since an idea to get somehow the length of the source stream looks at least strange, because of the asynchronous nature of the streams. It seems might be feasible by StatefullWidget with stream subsriptions (and setState invoking), but StreamBuilder is invented to do exactly the same, isn't it?

Your snapshot should be a list of elements so you can access the length of the list like this:

body: StreamBuilder(
        stream: someStream,
        initialData: [],
        builder: (ctx, snapshot) {
          return ListView.separated(
            separatorBuilder: (context, index) => Divider(color: Colors.black),
            itemCount: snapshot.data.length,
            itemBuilder: (BuildContext ctx, int index) {
                final element = snapshot.data[index];

I would suggest to add also the initialData to the StreamBuilder so you don't work with a null value in your snapshot.

Hope it helps

snapshot can have different states.

Generally you can do something like this:

if (snapshot.hasError){
    //return error message
}

if (!snapshot.hasData){
    //return a loader
}

//else you have data
List<your items> = snapshot.data;
// do your thing with ListView.builder

For more control you can check the snapshot.connectionsState which can be none , done , active , waiting .

You can find more here for the AsyncSnapshot class and here for a quick tutorial

try this hope it works for you

    body: StreamBuilder(
            stream: someStream,
            builder: (ctx, snapshot) {
              return ListView.separated(
                separatorBuilder: (context, index) => Divider(color: Colors.black),
                itemCount: snapshot.data.lenght,
                itemBuilder: (BuildContext ctx, int index) {
    final titre= snapshot.data[index].title ;  // for example

return ListTile ( title : Text(titre)) ;  
     //....

Like the other answers say, you can make your stream return the list, but that's what Future is for.

If you want your stream to incrementally yield values, you can declare the list inside the class, and add the values for each snapshot received right before the return statement.

You can still receive lists and append them to the bigger list which you would base your builder on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM