How to implement Pull-to-Refresh in Flutter

Last updated on January 18, 2021 A Goodman Loading... Post a comment

In this tutorial, we’ll build a simple Flutter app that fetches a to-do list from an open API and displays it on the screen. We also implement a Pull-to-Refresh feature that lets the user refresh the content by making a pulling down gesture.

Here’s the API url used in the app (thanks to the Typicode team):

https://jsonplaceholder.typicode.com/todos

It simply contains a list of todos (tasks). A single todo looks like this:

{
    "userId": 1,
    "id": 1,
    "title": "delectus aut autem",
    "completed": false
}

Getting Started

1. Project setup

Create a new Flutter project by running this command:

flutter create app_example

2. Installing the HTTP package to fetch data from APIs.

Find the dependencies section in your pubspec.yaml and add http: ^0.12.2, like this:

dependencies: 
  flutter:
    sdk: flutter
  http: ^0.12.2

Then run:

flutter pub get

3. Build the skeleton

Remove all the default code in main.dart and add this “skeleton” code:

import 'package:flutter/material.dart';
import 'dart:convert';
// import the http package
import 'package:http/http.dart' as http;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Hide the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // The initial todos
  List _todos = [];

  // Call this when the user pull down the screen
  Future<void> _loadData() async {
    
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Kindacode.com'),
      ),
      body: RefreshIndicator(
          // trigger the _loadData function when the user pulls down
          onRefresh: _loadData,
          // Render the todos
          child: ListView.builder(
              itemCount: _todos.length,
              itemBuilder: (BuildContext ctx, index) {
                // The List Item will be added later
              })),
    );
  }
}

Note: To implement Pull-to-Refresh, just wrap your widgets with a RefreshIndicator widget and configure the onRefresh property.

4. Loading data

Complete the _loadData function:

// Call this when the user pull down the screen
  Future<void> _loadData() async {
    final url = 'https://jsonplaceholder.typicode.com/todos';
    try {
      final http.Response response = await http.get(url);
      final _loadedTodos = json.decode(response.body);
      setState(() {
        _todos = _loadedTodos;
      });
    } catch (err) {
      throw err;
    }
  }

5. Render the list item

Add this code right after // The List Item will be added later, like this:

// The List Item will be added later
return Card(
                  margin: EdgeInsets.symmetric(horizontal: 15, vertical: 8),
                  child: ListTile(
                    // Render each todo
                    leading: Text(_todos[index]['id'].toString()),
                    title: Text(_todos[index]["title"]),
                    trailing: _todos[index]["completed"]
                        ? Icon(
                            Icons.check_circle,
                            color: Colors.blue,
                          )
                        : Icon(
                            Icons.circle,
                            color: Colors.yellow,
                          ),
                  ),
                );

6. The Final Code:

import 'package:flutter/material.dart';
import 'dart:convert';
// import the http package
import 'package:http/http.dart' as http;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Hide the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // The initial todos
  List _todos = [];

  // Call this when the user pull down the screen
  Future<void> _loadData() async {
    final url = 'https://jsonplaceholder.typicode.com/todos';
    try {
      final http.Response response = await http.get(url);
      final _loadedTodos = json.decode(response.body);
      setState(() {
        _todos = _loadedTodos;
      });
    } catch (err) {
      throw err;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Kindacode.com'),
      ),
      body: RefreshIndicator(
          // trigger the _loadData function when the user pulls down
          onRefresh: _loadData,
          // Render the todos
          child: ListView.builder(
              itemCount: _todos.length,
              itemBuilder: (BuildContext ctx, index) {
                return Card(
                  margin: EdgeInsets.symmetric(horizontal: 15, vertical: 8),
                  child: ListTile(
                    // Render each todo
                    leading: Text(_todos[index]['id'].toString()),
                    title: Text(_todos[index]["title"]),
                    trailing: _todos[index]["completed"]
                        ? Icon(
                            Icons.check_circle,
                            color: Colors.blue,
                          )
                        : Icon(
                            Icons.circle,
                            color: Colors.yellow,
                          ),
                  ),
                );
              })),
    );
  }
}

7. Check it out:

Conclusion

We have walked through an end-to-end example of implementing Pull-to-Refresh in a Flutter application with RefreshIndicator. If you would like to explore more interesting things about Flutter, take a look at the following articles: Load and display content from CSV files, Set an image Background for the entire screen, 3 Ways to create Random Colors in Flutter, Flutter Cupertino Button – Tutorial and Examples.

You can also check out our Flutter topic page or Dart topic page for the latest tutorials and examples.

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

Related Articles