Flutter:如何将 StreamBuilder 与 ListView.separated 一起使用

Posted

技术标签:

【中文标题】Flutter:如何将 StreamBuilder 与 ListView.separated 一起使用【英文标题】:Flutter: How to use StreamBuilder with ListView.separated 【发布时间】:2020-03-09 09:13:56 【问题描述】:

我想要一个包含来自 Stream 的项目的 ListView。 当然,List 的内容应该反映 Stream 的变化。 由于我的设计师怪癖,我希望 List 中的项目用分隔符分隔。

只是想知道,用分隔符创建 ListView 并对 Stream 更改做出反应的正确方法是什么。

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

希望我错过了什么。 由于流的异步性质,以某种方式获得源流长度的想法至少看起来很奇怪。 使用流订阅(和 setState 调用)的 StatefullWidget 似乎是可行的, 但是 StreamBuilder 被发明出来做同样的事情,不是吗?

【问题讨论】:

【参考方案1】:

您的snapshot 应该是一个元素列表,因此您可以像这样访问列表的length

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];

我建议将 initialData 也添加到 StreamBuilder,这样您就不会在快照中使用空值。

希望对你有帮助

【讨论】:

感谢您的回答。如果我想在加载数据时显示一个简单的加载小部件,我想知道如何处理空值问题。在这种情况下,initialData 将不起作用。【参考方案2】:

snapshot 可以有不同的状态。

通常你可以这样做:

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

如需更多控制,您可以查看snapshot.connectionsState,它可以是none,done,active,waiting

你可以找到更多here for the AsyncSnapshot class和here for a quick tutorial

【讨论】:

好的,现在我明白了,主要问题是我打算使用 Stream 而不是 Stream>。所以,由于 shanpshot 无法为我提供正确的信息,我成功地忽略了它。 (!snapshot.hasError) - 这将在没有错误时返回。 uopo,你是对的,有一个“!”那不应该在那里。已修复,谢谢! 是的,这里的见解是使用Stream&lt;List&lt;Data&gt;&gt; 而不是Stream&lt;Data&gt; 而不仅仅是检查!snapshot.hasData @papirosnik 嘿,我是 Flutter 新手,所以请回答我的新手问题 ;-) 如何将 Stream&lt;Data&gt; 转换为 Stream&lt;List&lt;Data&gt;&gt;?我的流来自 websocket (WebSocketChannel.connect(uri).stream),我想要一个带有收到消息日志的ListView。谢谢!【参考方案3】:

试试这个希望它对你有用

    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)) ;  
     //....

【讨论】:

以上是关于Flutter:如何将 StreamBuilder 与 ListView.separated 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中嵌套 StreamBuilder?

如何在 Flutter Web 上使用 StreamBuilder 和 Firestore?

如何在flutter中从streambuilder导航到其他页面?

如何在 Flutter 的 StreamBuilder 中使用 Future [重复]

Flutter:将firestore快照转换为streambuilder中的列表

Flutter/Firebase:如何减少对推送/弹出调用的 StreamBuilder 调用?