I want to create a behavior like Twitter App. So I scroll to the top of my list, I use a CupertinoSliverRefreshControl
to load new posts and want to place them on top of my current shown list with keeping my ScrollPosition.
To make usage of the CupertinoSliverRefreshControl
I need to use slivers
in a CustomScrollView
. onRefresh
I load new posts and add the old posts to it:
final _scrollController = ScrollController(keepScrollOffset: true);
return CustomScrollView(
controller: _scrollController
physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
slivers: <Widget>[
CupertinoSliverRefreshControl(
onRefresh: () {
// loading new posts. I set state with blocBuilder but for easiness I show it with setState here:
setState(() { posts = List.from(newPosts..addAll(posts)); })
}
),
SliverList(
delegate: SliverChildBuilderDelegate((context, index) {
return PostCard(posts[index]);
},
childCount: posts.length)
)
]
);
Saving the ScrollPosition
with a ScrollController
is not working because it always saves the offset to the top and not to the bottom. In my case, the offset to the top will change by loading new posts.
I also tried to build the old posts and the new posts in two different SliverLists
. To the SliverList
with old posts, I added a key and set the center
of my CustomScrollView
to this key. Doing so crashes my CupertinoSliverRefreshControl
.
Also, I cannot just use the list reversed because I want a loading into the other direction as well in a further development state.
You can use ScrollController.position
for this:
// You will need to place the following code snippets in appropriate locations.
double extentAfter;
// Save the current offset from the bottom:
extentAfter = _scrollController.position.extentAfter;
// After your loading is done, you can apply the saved extentAfter:
_scrollController.jumpTo(_scrollController.position.maxScrollExtent - extentAfter);
I do not exactly know how your setup works, but I could imagine that saving the extentAfter
can be done in a listener of your ScrollController
(because you want to have the latest extentAfter
before the new items are inserted) and jumping to the "new" position when rebuilding the scroll view.
You can not call jumpTo
when rebuilding by supplying a new ScrollController
:
// Update your scroll controller with the new position.
_scrollController = ScrollController(
initialScrollOffset: _scrollController.position.maxScrollExtent - extentAfter
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With