Flutter ListView scroll to bottom on build

Viewed 7749

Is it possible to make a Flutter listview scroll to the bottom after it initially loads all its data? I am aware of the scrollController.jumpTo() logic, however this has to be called within some event handler, how would you invoke this upon the completion of a listview building so as soon as the screen opens it scrolls to the bottom?

2 Answers

Well, I think you are in the correct track to achieve it!

You should try _controller.jumpTo() and fire that event programatically.

You can create a Timer, and call the _controller in there, after 500 milliseconds (half of a second).

ScrollController _myController = ScrollController();

@override
Widget build(BuildContext context) {
      
      // here we set the timer to call the event
      Timer(Duration(milliseconds: 500), () => _myController.jumpTo(_myController.position.maxScrollExtent));

      // add _myController to the ListView
      return ListView.builder(
         controller: _myController,
         // itemCount: yourItemsCount,
         // ...
      )
}

Please check this answer also --> Programmatically scrolling to the end of a ListView

And also this one --> How to get full size of a ScrollController

There they use SchedulerBinding.instance.addPostFrameCallback which I think is also a good solution to fire your scroll.

SchedulerBinding.instance.addPostFrameCallback((_) {
            _myController.animateTo(
              _myController.position.maxScrollExtent,
              duration: const Duration(milliseconds: 500),
              curve: Curves.easeOut,
            );
          });

UPDATE:

Please try this code, no transition, no visible jump to me.

Is a combination of my previous paragraphs.

Just beware, if the number of lines grow, like 10000.

But I think you should control the number of messages displayed.

  Widget build(BuildContext context) {
    final items = List<String>.generate(50, (i) => "Item $i");

    ScrollController _controller = ScrollController();

    SchedulerBinding.instance.addPostFrameCallback((_) {
        _controller.jumpTo(_controller.position.maxScrollExtent);
      });

    return Scaffold(
        body: SafeArea(
          child: ListView.builder(
            controller: _controller,
            itemCount: items.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text('${items[index]}'),
              );
            },
          ),
        ));
  }

I think the main problems why ListView.builder cannot show all of items to the bottom depends on whether you put the downloaded data from Database (Firestore) inside a class or not. In my case, it did. So I transferred all downloaded data (QuerySnapshot) into another class or GetX controller and loaded all of them from that data.

Related