如何存储流数据并在颤动列表视图中显示新的和旧的?

Posted

技术标签:

【中文标题】如何存储流数据并在颤动列表视图中显示新的和旧的?【英文标题】:How to store stream data and display new one along with old in a flutter list view? 【发布时间】:2021-06-28 03:08:46 【问题描述】:

我正在尝试显示来自 Reddit API 的评论流。我正在使用 Streambuilder 在内容到达时对其进行流式传输并将其显示为列表视图 事情是我只能查看当前的流内容,并且随着新的流内容出现替换旧的内容,这将消失。如果我没有在列表视图中提及项目计数.builder 无限打印内容仍然出现新的流。

有没有办法以可滚动的方式显示内容和以前的内容,并在出现新的流消息时自动向下滚动??

【问题讨论】:

使用Stream.map()方法 你能告诉我怎么做吗?或分享一些参考@pskink dart.dev/tutorials/language/streams#modify-stream-methods 【参考方案1】:

假设评论流一次返回一个单独的(最好是唯一的)cmets,而不是作为一个列表,您需要做的是将传入的 cmets 存储在一个状态对象中,例如一个列表。当流中出现新评论时,您将其添加到列表中,然后触发小部件重建。

您现在正在做的是用每个新的流元素替换状态,而不是累积它们。使用您提供的代码,我已将其编辑为充当累加器。注意添加到状态的List<Comment> comments = <Comment>[] 对象。我还删除了 StreamBuilder,因为这对这个用例没有帮助。

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:draw/draw.dart';

void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      home: RedditFlutter(),
      debugShowCheckedModeBanner: false,
    );
  


class RedditFlutter extends StatefulWidget 
  RedditFlutter(Key key) : super(key: key);

  @override
  _RedditFlutterState createState() => _RedditFlutterState();


class _RedditFlutterState extends State<RedditFlutter> 
  var comments;
  ScrollController _scrollController =
      new ScrollController(initialScrollOffset: 50.0);
  List<Comment> comments = <Comment>[];
  StreamSubscription<Comment>? sub;

  var msg = '';
  Future<void> redditmain() async 
    // Create the `Reddit` instance and authenticated
    Reddit reddit = await Reddit.createScriptInstance(
      clientId: 'clientid',
      clientSecret: 'clientsecret',
      userAgent: 'useragent',
      username: 'username',
      password: 'password', // Fake
    );

    // Listen to comment stream and accumulate new comments into comments list
    sub = reddit.subreddit('cricket').stream.comments().listen((comment) 
      if (comment != null) 
        // Rebuild from state when a new comment is accumulated
        setState(() 
          comments.add(comment);
        )
      
    );
  

  @override
  void initState() 
    // TODO: implement initState
    redditmain();

    super.initState();
  


  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text("Reddit"),
        centerTitle: true,
      ),
      body: Center(
        child: Container(
                child: ListView.builder(
                  controller: _scrollController,
                  itemCount: comments.length,
                  itemBuilder: (context, index) 
                    final Comment comment = comments[index];
                    return Card(
                      child: ListTile(
                        leading: Image.asset('assets/criclogo.png'),
                        title: Text(comment.body),
                        trailing: Icon(Icons.more_vert),
                      ),
                    );
                  ,
                ),
              );
      ),
    );
  

  @override
  void dispose() 
    sub?.cancel();
    super.dispose();
  

请注意,我尚未测试此代码,因此可能存在(微不足道的)错误。不过,从概念上讲,它应该没问题。

【讨论】:

以上是关于如何存储流数据并在颤动列表视图中显示新的和旧的?的主要内容,如果未能解决你的问题,请参考以下文章

颤动中滚动视图内的Listview

如何在颤动中使用流构建器刷新小部件

如何在颤动中创建加载更多列表视图

如何在firestore中显示地图列表并在颤动中显示它们

显示列表中的随机 10 个元素颤动 [关闭]

新的 TFileOpenDialog 和旧的 TOpenDialog 有啥区别?