EdsonBueno / infinite_scroll_pagination

Flutter package to help you lazily load and display pages of items as the user scrolls down your screen.
https://pub.dev/packages/infinite_scroll_pagination
MIT License
632 stars 215 forks source link

[Question] Handle new items in addition to old ones #101

Closed rocboronat closed 3 years ago

rocboronat commented 3 years ago

I'm trying to build a chat messages list. You know: filling it with the latest messages as soon as the user opens the screen, letting the user see older messages with a lazy load (that is the focus of this package), but also update the list with new messages and scroll to them in case the user was in the bottom of it. You know, the regular Telegram and WhatsApp list of messages behavior.

I've checked the example and I've seen how to add more elements to the end of the page. But is there a way to also handle new items, and scroll to them automatically in case the user was already at the bottom of the list?

Congrats on this great package, by the way :ยท)

EdsonBueno commented 3 years ago

Hi @rocboronat. Thank you for opening this issue and giving this package a chance.

What you want is a reverse PagedListView (or PagedSliverList depending on how complex your layout is), which can be accomplished by setting reverse: true inside the widget's constructor. Think of it as a regular paginated list turned upside down. So, for instance, when you open the screen, you'll be seeing the first page (the newer messages), and as you scroll up, you'll fetch new pages (for the older messages). This solves the first part of the puzzle (showing older messages).

The second part of the puzzle is displaying newer messages as they arrive, and for that you'll just have to be listening to something (probably some Socket, depending on how your back-end is structured). When you get notified about new messages, you simply reassign the updated list to your PagingController. Something like this:

final alreadyDisplayedMessages = _pagingController.itemList;
_pagingController.itemList = [...newMessagesThatHaventBeenDisplayedYet, ...alreadyDisplayedMessages];

That will take care of refreshing your list with the newer items.

I hope I was helpful.

rocboronat commented 3 years ago

Thanks for the suggestion, @EdsonBueno!

If I do so, I'm afraid it will make a direct jump to the bottom of the List, instead of being able to scroll smoothly to it. Am I wrong? I mean, redefining itemList won't just reassemble the whole list of items, causing the List to abruptly scroll to another's position?

You know, when you add an item to position 0 of an already visible list, all the content just swaps positions, without any animation.

rocboronat commented 3 years ago

Hi again @EdsonBueno! Just tried it and it seems it happens: when adding an element to position 0, the whole list "jumps".

Do you think it's on the scope of this package to handle it, or do you want to just offer the previous page feature?

EdsonBueno commented 3 years ago

I see it now. The thing is, the way these chat apps work is:

  1. If the user hasn't scrolled up yet when new messages arrive, jump to the bottom.
  2. If they have scrolled up when new messages arrive, don't jump to the bottom.

So, it's not as simple as: never jump to the bottom.

The way I think you can accomplish that is by creating a custom logic using ScrollController and then providing that controller to your PagedListView.

rocboronat commented 3 years ago

I've done it ๐Ÿ˜… but it doesn't work like that. You cannot tell the scroll to lock the position, because it is not aware of the content change. So, you can do such special things when adding content to the end of the list (as you do), but not to the beginning of it.

Of course, you can reverse the list...

But then you can do great things to the beginning of the list, but the end of the list will jump when adding content to it ๐Ÿ’ฉ

Oh, by the way, answering to your message: on great apps, the list never jumps. They always lovely animate. I've achieved it on native Android but not on Flutter ๐Ÿ˜…

EdsonBueno commented 3 years ago

Apparently #56 will help you then. What are your thoughts?

samerset-rmn commented 2 years ago

Oh, by the way, answering to your message: on great apps, the list never jumps. They always lovely animate. I've achieved it on native Android but not on Flutter ๐Ÿ˜…

Hi @rocboronat! Sorry for approaching you at this closed topic, but I'd really like to know how did you solve that task? I'm in process of creating the same logic in my app.

rocboronat commented 2 years ago

Hello ๐Ÿ‘‹!

I didn't approach it properly yet. Right now I'm hiding the list while scrolling to the top or the bottom of the list, and when the scroll is finished, I make the list visible again. So sad. But if I had time, I would check #56 as @EdsonBueno suggested ๐Ÿ˜„

By the way, @EdsonBueno, I didn't try it yet, but thanks for the link! ๐Ÿ‘

samerset-rmn commented 2 years ago

Alright, thanks! I'll figure something out.