Flutter – Implementing pull to refresh

In this post I’ll explore just how easy it is to implement pull to refresh on a flutter application.  If you are not familiar with pull to refresh, where have you been?  All joking aside, this is a UI pattern where you have a list of items displayed in your mobile app and you “pull” or “swipe” the list down to refresh.  I’m not sure why but some people love this and some people hate it – for example in this Fast Company article it is cited as boring and must die – Why the pull-to-refresh gesture must die.  Dramatic? – Indeed! Is it correct? – well you decide…  But I assume you came here because you wanted to know how to implement pull to refresh in Flutter so let’s dive in.

Our application

Instead of starting a new application from scratch, we’ll use the stock watcher application that I created in a prior post.  You can get up and running quick with this app by cloning the repository.  However if you don’t want to follow along and want to jump ahead, the finished application is out on github as well.

Once you have the application up and running, we are ready to add pull to refresh.  It would make sense first of course if you added a few stocks to the list since the application does not come with any stock tickers loaded nor does it persist your ticker symbols (I plan on covering persisting data in future posts).  Here is what I have ready for me to use for this exercise:

 

Adding a last refreshed date

Since the stock quotes we are pulling from our API are not in real-time but instead 15-minute delayed, we may not see the results of our update unless 15 minutes has elapsed and the price has changed.  So just to make sure things are working, we will add a timestamp to the item to show when it was last refreshed.  Open up the stock.dart code and add a lastUpdated property to the Stock class:

class Stock {
  String symbol;
  double price;
  DateTime lastUpdated;

  Stock(this.symbol, this.price);
}

Next we will set the lastUpdated value whenever a stock is added for the first time.  Open up the main.dart file and find the onPressed implementation.  Within this block of code we need to set the lastUpdated to the current date and time.

onPressed: () async {
    if(_model.isNotEmpty) {
      double price = await _stockService.getPrice(_model);
      setState(() {
        var s = new Stock(_model, price);
        s.lastUpdated = new DateTime.now();
        _stockList.add(s);
      });
    }                  
      _model = "";                  
  Navigator.pop(context);
},

And of course we have to handle displaying the actual value of lastUpdated on the user interface.  Crack open stock_list.dart and locate the _buildStockList method.  We will need to change the creation of the ListTile so that we can dispay the lastUpdated value.  Here is the new code:

return ListTile(
    title: Text('${s.symbol}'), 
    subtitle: Text(
       '${s.price ?? "price not found"}' + ", last updated: ${s.lastUpdated}")
);

Now, if you run the app and add a new stock, you will see the last updated displayed.  For example:

 

Note – if this were a production quality application, I would consider a more user friendly way of displaying those dates!

Pull to refresh

Getting pull to refresh to work in flutter is actually straight-forward once you know the bits and pieces.  For our example, we just need to do two things:

  1. Add a RefreshIndicator
  2. Specify a method to call when the refresh is requested.

To add a RefreshIndicator, open up main.dart and modify the build method so that we wrap the StockList widget with a RefreshIndicator as follows:

body: new Container(
        child: new Center(
          child: new RefreshIndicator(
            child: new StockList(stocks: _stockList),
            onRefresh: _refreshStockPrices,
          ) 
        ),
      ),

And to finish out our example, we need the code that the RefreshIndicator.onRefresh calls:

Future<void> _refreshStockPrices() async
  {
    print('refreshing stocks...');
    _stockList.forEach((s) async {
      double price = await _stockService.getPrice(s.symbol);
      setState(() {
        s.price = price;
        s.lastUpdated = new DateTime.now();              
      });
    });
  }

The implementation of _refreshStockPrices is simple – iterate the current list of stocks and asynchronously (for more on async and await, see my Dart fundamentals article). call the getPrice method of our stock service.  Once a price is obtained, we update the price as well as the lastUpdated timestamp.  Here is how it looks in action:

Summary

Pull to refresh was amazingly simple to implement in Flutter.  All you need is to add a RefreshIndicator and provide an implementation for onRefresh.  I hope you enjoyed learning about refreshing a list in Flutter!  Until next time…

1 thought on “Flutter – Implementing pull to refresh”

Leave a Reply

Your email address will not be published. Required fields are marked *