Flutter — How to make your ScrollView support pull-to-refresh?
It’s an useful behavior on the mobile app that when we scroll to the top of a vertical scroll view, and overscroll, a refresh indicator will drop down, then the new data updates after we release the control. Flutter provides a handy widget called
RefreshIndicator for this purpose.
As the official documentation says,
RefreshIndicator is a widget that supports the Material “swipe to refresh” idiom. Today, we’re going to learn how to implement it in our ScrollView.
Table of Contents
- Cupertino style of refresh indicator in iOS.
- Known issues with
Let’s try to display 100 random numbers which are generated from
Random().nextInt() at the beginning. After pulling to refresh, a new list of random numbers will be regenerated and display on the screen.
Follow the steps to achieve it:
- Wrap your
RefreshIndicatorlike L36 does.
- Provide a future task to the parameter
onRefreshin L37. The purpose of the future task is to fetch the new data, then refresh the widget.
RefreshIndicator in CustomScrollView
RefreshIndicator can also be used for
CustomScrollView. As the following code, we create a
CustomScrollView with a SliverList and a SliverGrid. You can refer to my previous post for the CustomScrollView details.
The main function is in L36 to L44, we wrap a
CustomScrollView into a
RefreshIndicator. Then we can achieve the purpose of pulling to refresh the whole ScrollView. It is quite easy, right?
There are also some parameters we can use to change the UI.
The distance from the child’s top or bottom edge to where the refresh indicator will settle.
- color/background color, stroke width of the indicator:
Cupertino style of refresh indicator in iOS
We can also change the style of refresh indicator to Cupertino style.
CupertinoSliverRefreshControl is an iOS equivalent of the pull-to-refresh pattern. Here is the documentation:
Must be used as a sliver inside a [CustomScrollView] instead of wrapping around a [ScrollView] because it's a part of the scrollable instead of being overlaid on top of it.
According to it, the implementation will be like:
in L39, we wrap
CupertinoSliverRefreshControl into a
CupertinoSliverRefreshControl is a sliver widget implementing the iOS-style pull-to-refresh content control. That’s why we need to put it in the
CustomScrollView. Here is what it looks like on iOS:
Everything works like a charm on iOS, however, it doesn’t work on Android directly.
CupertinoSliverRefreshControl doesn't work on android · Issue #27977 · flutter/flutter
You can't perform that action at this time. You signed in with another tab or window. You signed out in another tab or…
Please checkout the reason and solution here:
This is working as intended. It’s due to the
ScrollPhysicswhich is used on Android. iOS uses
BouncingScrollPhysicswhich doesn't apply any boundary conditions when
applyBoundaryConditionsis called i.e. it allows for under/overscrolling. If you want the same effect on Android you can use
BouncingScrollPhysicswhich will give you the an iOS feel on Android, or you can override
ClampingScrollPhysicswhich is what Android uses.
So we can fix it by using
Widget build(BuildContext context) => CustomScrollView(
physics: const BouncingScrollPhysics(),
I’ve tried to implement pull-to-refresh function on the WebView, however, it didn’t seem to work. Then I found an issue on the Flutter Github about this.
RefreshIndicatoror similar functionality isn’t compatible with
Unfortunately, we need to wait for the Flutter team to solve it.
That’s all for today. Thank you for reading this article. Hope it helps you to learn more about how the implement RefreshIndicator in all your ScrollView. If you have any suggestions or questions, welcome to leave a comment below. See you next time 🙌.
- RefreshIndicator official documentation:
A widget that supports the Material "swipe to refresh" idiom. When the child's Scrollable descendant overscrolls, an…
- An article about the details of implementing pull-to-refresh behavior: