Flutter/Firestore: How to add items to stream on scroll (preserve scrollposition when done fetching)?

822

This issue is not related to ListView or the scroll position. Those are kept with automatically. The issue must be somewhere else in your code. Check my example below to see how having a list, adding new items and then resetting it, will maintain the scroll position or move to the right place:

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');
    });
  }
}
Share:
822
Isaak
Author by

Isaak

Updated on December 18, 2022

Comments

  • Isaak
    Isaak over 1 year

    I have a chat (ListView) with messages that I only want to load as needed.

    So when the chat is initially loaded I want to load the last n messages and when the user scrolls up I want to fetch older messages also.

    Whenever a new message arrives in the firebase collection it should be added to the ListView. I achieved this by using a StreamBuilder that takes the stream of the last n messages where n is a variable stored in the state that I can increase to load more messages (it is an argument to the function that gets the stream of the last n messages).

    But with my current implementation the problem is that even though more messages are fetched and added to the listview when I scroll up, it then immediately jumps back to the bottom (because the listview is rebuilt and the scrollposition isn't preserved). How can I prevent this from happening?

  • Isaak
    Isaak about 4 years
    This code adds items to a list only when a button is pressed but I want to include more documents in the stream for my Streambuilder when a new message arrives in the collection.
  • J. S.
    J. S. about 4 years
    The button is only representing the same effect as receiving new data from a Stream. The purpose is the same. I am showing you that the issue is not with the display of the information in the ListView, it has to be somewhere else in your code.
  • Isaak
    Isaak about 4 years
    I think I see your point. Maybe the problem with preserving the scrollposition arose because I had the streambuilder inside a stateless widget and whenever the streambuilder was rebuilt (because I changed the query that gets the stream). The scrollcontroller was rebuilt and didn‘t have the last scrollposition. I‘ll try it out and post it here if it worked.
  • Pedro Romão
    Pedro Romão about 3 years
    Thanks a lot. I've actually found my problem based on your answer.
  • J. S.
    J. S. about 3 years
    I'm glad I could help!
  • Community
    Community almost 2 years
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.