Flutter/Firestore:如何在滚动时将项目添加到流中(完成获取时保留滚动位置)?

Posted

技术标签:

【中文标题】Flutter/Firestore:如何在滚动时将项目添加到流中(完成获取时保留滚动位置)?【英文标题】:Flutter/Firestore: How to add items to stream on scroll (preserve scrollposition when done fetching)? 【发布时间】:2020-06-16 16:04:21 【问题描述】:

我有一个聊天 (ListView) 消息,我只想根据需要加载。

因此,最初加载聊天时,我想加载最后 n 条消息,而当用户向上滚动时,我还想获取较旧的消息。

每当有新消息到达 firebase 集合时,都应将其添加到 ListView。我通过使用StreamBuilder 来实现这一点,它获取最后 n 条消息的流,其中 n 是存储在状态中的变量,我可以增加它以加载更多消息(它是获取最后一条消息流的函数的参数n 条消息)。

但是对于我当前的实现,问题是即使在我向上滚动时获取更多消息并将其添加到列表视图中,它也会立即跳回底部(因为列表视图已重建并且滚动位置未保留) .我怎样才能防止这种情况发生?

【问题讨论】:

你应该看看问题指南:***.com/help/how-to-ask 【参考方案1】:

此问题与 ListView 或滚动位置无关。这些是自动保存的。问题必须在您的代码中的其他地方。查看下面的示例,了解如何拥有一个列表、添加新项目然后重置它,将如何保持滚动位置或移动到正确的位置:

class ListViewStream60521383 extends StatefulWidget 
  @override
  _ListViewStream60521383State createState() => _ListViewStream60521383State();


class _ListViewStream60521383State extends State<ListViewStream60521383> 
  List<String> _itemList;

  @override
  void initState() 
    resetItems();
    super.initState();
  


  @override
  Widget build(BuildContext context) 
    return Column(
      children: <Widget>[
        Expanded(
          child: ListView.builder(
            reverse: true,
            itemCount: _itemList.length,
            itemBuilder: (context, index)
              return Container(
                height: 40,
                child: Text(_itemList[index]),
              );
            ,
          ),
        ),
        Row(
          children: <Widget>[
            RaisedButton(
              onPressed: addMoreItems,
              child: Text('Add items'),
            ),
            RaisedButton(
              onPressed: resetItems,
              child: Text('Reset items'),
            )
          ],
        )
      ],
    );
  

  void addMoreItems()
    int _currentListCount = _itemList.length;
    setState(() 
      _itemList.addAll(List.generate(60, (index) => 'item $index + _currentListCount'));
    );
  

  void resetItems()
    setState(() 
      _itemList = List.generate(60, (index) => 'item $index');
    );
  

【讨论】:

此代码仅在按下按钮时将项目添加到列表中,但我想在集合中收到新消息时在 Streambuilder 的流中包含更多文档。 该按钮仅代表与从 Stream 接收新数据相同的效果。目的是一样的。我正在向您展示问题不在于 ListView 中信息的显示,它必须在您的代码中的其他位置。 我想我明白你的意思了。可能会出现保留滚动位置的问题,因为我将流构建器放在无状态小部件中,并且每当重新构建流构建器时(因为我更改了获取流的查询)。滚动控制器已重建并且没有最后的滚动位置。如果可行,我会尝试并在此处发布。 非常感谢。根据您的回答,我实际上已经找到了我的问题。 很高兴能帮上忙!

以上是关于Flutter/Firestore:如何在滚动时将项目添加到流中(完成获取时保留滚动位置)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter Firestore 提供程序中显示数据

如何使用flutter cloud_firestore包传递firestore auth token

如何在 Flutter Firestore 中读取数组的 FieldValues

Flutter / Firestore - 如何访问 Firebase 上的嵌套元素?

如何检查 Flutter Firestore 中是不是存在用户文档?

如何在 Flutter Firestore 中查询 2 个文档并作为列表返回?