scroll position of listview changed if I add multiple elements from top in list. It’s working fine for insert operation when we inster new elements in the bottom of the list.
Usecase is there is one chat module in my application & I have to implement both side pagination (up & down) in that. If user scroll up then normal pagination flow, items added in the bottom of the list so it’s working fine. But if user user scroll down then new items added at the top of the list & scroll position changed.
I have searched in all place & tried all solution but didn’t found any proper solution & many people also faced the same issue.
I am attaching a one dartpad link of this issue : open dartpad
Step to reproduce:
-
run the app, scroll to end of the list
-
now click on add icon, it will add 30 items in top of the list & you will notice scroll position will change after that
-
in this example I’m using setState but the same thing will happen even after using any state management solution.
-
I’m expecting not to change scroll position if I add elements from top of the list
2
Answers
you just need one more function called
scrollTop
that needs to call inside_incrementCounter
functionDemo:
Below is fixed your code example:
Actually, the problem is that the viewport would layout its slivers using the new maxScrollExtent (that increased due to the newly added items). However, the
ScrollPosition.pixels
is still unchanged, while existing slivers have received their new scroll offset in theirSliverGeometry
.Consequently, slivers would paint their items using the new scroll offset and the old
ScrollPosition.pixels
(that would be updated once the painting is completed for the current frame).Therefore, we have three ways to align the new scroll offset and the old pixels.
jumpTo(diff)
usingaddPostFrameCallback
, like below:This way would meet your requirements but the painting may flicker between the two frames since you actually do
JumpTo
normally. See the video link.ScrollController
and create a customScrollPosition
to align the pixel difference when the viewport invokesViewportOffset.applyContentDimensions
duringperformLayout()
. Eventually, you could invokeRetainableScrollController.retainOffset()
to keep the scroll position when inserting new items at the top of the list view.The demo video could be found [here]
ScrollPhysics
. Though this way, you do not need to change your existing codes, and just passphysics: const PositionRetainedScrollPhysics()
in your list view.