How to create your own pull to refresh / custom refresh indicator widget in Flutter.
A few months ago in a project that I was working on, there was a need to create a custom refresh indicator to replace the default indicator provided with a flutter material library. Back in those days, I found it really hard to find some simple solutions or packages that will provide basic functionality on which I will be able to implement it. The one and only thing that I was able to find was liquid_pull_to_refresh package that was just modification of the default material design refresh indicator widget, and I was like…
To avoid another: copy, paste, refactor and forgot why this file has over a thousand lines of code — type of work which almost always ends in some production f… problems. I have created custom_refresh_indicator_package (available on pub.dev).
The main target of this package was to provide all data needed for pull to refresh functionality implementation in as simple way as possible.
Below you can see an example indicator created on top of this package.
Okey… now we know that someone sometime for some reason might like to implement its own unique pull to refresh indicator.
Let’s imagine that we have a simple screen which looks like this:
and which is written like this:
To add pull to refresh functionality we must wrap the list widget with CustomRefreshIndicator widget that is provided by
Let’s take a look at changes.
First of all, we have added an import statement to the
custom_refresh_indicator package, because we would like to build our indicator on top of it.
In the same way, as we are using
RefreshIndicator widget we assigned a function that will return
Future to the onRefresh argument. In the above example, we returned
Future.delayed() as we do not want to take any action instead we just want to wait for a few seconds to simulate asynchronous function behavior, but basically this is the place when you are doing your API call or other asynchronous functions that will take an effect after the pull to refresh gesture is done on your list.
We assigned our scrollable widget into the child argument —still the same way as we would like to this with the
The builder argument is something that its new in comparison to RefreshIndicator. This function will be used to build our pull to refresh widget. It takes three arguments in turn: the context of type
BuildContext, child of type
Widget and controller of type
- BuildContext — It’s a quite common argument so I think that I can skip it 😉.
- The child argument is basically the scrollable widget that we assigned to the child widget argument (quite similar behavior to that known from
AnimatedBuilderwidget). So if we for some reason do not want to render our list we can skip the use of it — but it almost always makes no sense 😄.
- The third and most important argument is the controller of type
IndicatorController. This argument contains all information about the scroll state that we would like to use to build our custom indicator. Controller extends
ChangeNotifierclass, thanks to this we can listen to its changes.
Builder function will not be called every controller data change so to animate your indicator widget you should consider using
So… the above example will provide a pull to refresh behavior (user can drag the list to call
onRefresh function but) without visual effect because the
builder function always returns our list without any changes. So when talking about user experience…
But if for some reason we find that our users should suffer a little less, just a little 🤏. We would like to add some effect, so let’s do this!
As you can see we have added
AnimatedBuilder widget that listens to changes notified by
Stack widget with some
Transforms in it, and that's the effect:
To better understand how controller data changes let’s look at the below example.
As you can see to implement your own custom refresh indicator widget you do not need to copy dozens of lines of code that you even do not understand from libraries of other people to your project code. Instead, add a custom refresh indicator package to your
pubspec.yaml file and implement a few lines of
builder function. That’s it, isn’t it simple 😏?
Do not wait! Create your own custom refresh indicator!