1

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

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

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

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

4

1 回答 1

2

此问题与 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');
    });
  }
}
于 2020-03-04T09:03:49.093 回答