Flutter - how to scroll to the bottom of a listview?

708

Solution 1

I finally found a solution. None of the answers worked for me, or worked partially, but I appreciate your attempts to answer.

For me all i had to do was put

reverse: true

in the ListView builder and then whenever you return the message you need to return it as:

return messages[messages.length - 1 - index];

This is the most important part.

Solution 2

what i did, use a listView and reverse true and in children use the list of map.reversed, i am giving you my code example below.

ListView(
          reverse: true,
          children: controller.listMessageData.reversed
           .map((e) => Container(child: Text(e.title));

Solution 3

Just a workaround but it should work as expected. Use clamping physics in the list view. Add an extra number to the max extent

 _scrollController.animateTo(
 _scrollController.position.maxScrollExtent+300,
 duration: const Duration(
   milliseconds: 200,
  ),
  curve: Curves.easeInOut,
  );

Solution 4

Use ScrollController for that it works smooth and simple to use

ScrollController _scrollController = new ScrollController();

Add controller to LisView like this :

 ListView.builder(controller: _scrollController,)

In your initState to scroll to bottom when navigating to this screen

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

    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (_scrollController.hasClients) {
        _scrollController.animateTo(
          _scrollController.position.maxScrollExtent,
          curve: Curves.easeOut,
          duration: const Duration(milliseconds: 500),
        );
      }
    });
}

Solution 5

Use should use the reverse property.

ListView.builder(
  reverse: true,
  itemCount: 10,
  itemBuilder: (_, index) {
    return ListTile(title: Text(index.toString()));
  },
)
Share:
708
busuu
Author by

busuu

Updated on January 01, 2023

Comments

  • busuu
    busuu over 1 year

    I use this code to scroll:

    WidgetsBinding.instance?.addPostFrameCallback((_) => _scrollToEnd());
    

    _scrollToEnd() method is:

    _scrollController.animateTo(
      _scrollController.position.maxScrollExtent,
      duration: const Duration(
        milliseconds: 200,
      ),
      curve: Curves.easeInOut,
    );
    

    Imagine this as a normal chat screen. It scrolls to the bare bottom if the messages are in 1 line. But as soon as a message gets to 2+ lines it struggles to scroll to the bare bottom. The more rows of a message the less it scrolls to the bottom.

    This is how it looks like when i enter the chat:

    But if i scroll down further this is the bottom of the chat:

    I noticed there's also a case when:

    1. I enter the chat.
    2. It scrolls down like on the first image.
    3. If i tap anywhere on the screen, it continues to scroll to the bare bottom of the listview like on the second image.

    Why does this happen and how do i fix this?

    • Yeasin Sheikh
      Yeasin Sheikh over 2 years
      can you include a list item and what are using for bottom-Widget?
    • Albert221
      Albert221 over 2 years
      Please look at the @Alwayss Bijoy answer. I think you are asking the wrong question and his answer is probably the thing you need/you'd want to use :)
  • busuu
    busuu over 2 years
    I tried that and it's the same problem
  • busuu
    busuu over 2 years
    This is the closest answer so far. It worked and now it scrolls to the bare bottom. However I noticed that there's no "drag beyond bottom" effect on ios, because of the clamping physics. Is it possible to preserve this effect?
  • Kaushik Chandru
    Kaushik Chandru over 2 years
    You can change the physics to bouncephysics or a normal scrollphysics but you may see an extra bounce to the end and then it will snap in its place which may look a bit odd
  • busuu
    busuu over 2 years
    Yes I noticed there's a bounce effect now. Is there a way to fix this too?
  • Kaushik Chandru
    Kaushik Chandru over 2 years
    Try approximate value to add. For example if the last message is 4 lined. Add a value as 120 (30x4). That way you can use any physics of your choice and it wouldn't bounce.