Flutter – Implementing Pull to Refresh
Last Updated :
09 Apr, 2025
The pull-to-refresh or (swipe-to-refresh) feature enables a user to pull down to fetch more data. The pull-to-refresh feature can be seen in many modern apps. The pull-to-refresh feature can be implemented in those components that are scrollable.
In this article, we are going to implement this feature in Flutter. Flutter is all about widgets; everything in Flutter is nothing but widgets and also it provides a widget to implement this feature as well as i.e. , RefreshIndicator.
RefreshIndicator: When the child’s Scrollable descendant overscrolls, an animated circular progress indicator is faded into view. When the scroll ends, if the indicator has been dragged far enough for it to become completely opaque, the onRefresh callback is called. The callback is expected to update the scrollable’s contents and then complete the Future it returns. The refresh indicator disappears after the callback’s Future has completed.
To create a flutter application, open the terminal/ command and run the below command:
flutter create app_name
// app_name should be the name of your app
To know more about it refer this article: Creating a Simple Application in Flutter.
After running this command, you should have a folder with the specified app_name. Navigate into that folder and open lib/main.dart file.
Note: In order to implement pull-to-refresh feature we are not going to use any other dependencies.
To create a RefreshIndicator, use the below syntax:
RefreshIndicator(
child: ...
onRefresh: ...
)
These are required fields.
- child: Should be a scrollable widget
- onRefresh: A function that should return a future.
Step-by-Step Implementation
Step 1 : Prepare Some Sample Data
As discussed above, for RefreshIndicator to wor,k we are going to need a scrollable component. So, for that, we are going to use ListView. In this step, we are going to define some demo data for our app.
Dart
// Local State to display items in listview
List<String> _demoData;
// This method will run once widget is loaded
// i.e when widget is mounting
@override
void initState() {
// initializing state / demo data
_demoData = [
"Flutter",
"React Native",
"Cordova/ PhoneGap",
"Native Script"
];
super.initState();
}
Step 2 : Build a ListView
We are going to create our ListView with ListItem and AlwaysScrollingPhysics.
Dart
//... some code
ListView.builder(
itemBuilder: (ctx, idx) {
// List Item
return Card(
child: ListTile(
title: Text(_demoData[idx]),
),
);
},
// Length of the list
itemCount: _demoData.length,
// To make listView scrollable
// even if there is only a single item.
physics: const AlwaysScrollableScrollPhysics(),
)
//... some code
Step 3 : Wrap with RefreshIndicator
Finally, wrap ListView into RefreshIndicator to use the pull-to-refresh feature.
Dart
// ... some code
RefreshIndicator(
child: ListView.builder(
itemBuilder: (ctx, idx) {
// List Item
return Card(
child: ListTile(
title: Text(_demoData[idx]),
),
);
},
// Length of the list
itemCount: _demoData.length,
// To make listView scrollable
// even if there is only a single item.
physics: const AlwaysScrollableScrollPhysics(),
),
// Function that will be called when
// user pulls the ListView downward
onRefresh: () {
return Future.delayed(
Duration(seconds: 1),
() {
/// adding elements in list after [1 seconds] delay
/// to mimic network call
///
/// Remember: setState is necessary so that
/// build method will run again otherwise
/// list will not show all elements
setState(() {
_demoData.addAll(["Ionic", "Xamarin"]);
});
// showing snackbar
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text('Page Refreshed'),
),
);
},
);
},
)
// ... some code
Complete Source Code
main.dart:
Dart
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GeeksforGeeks',
// to hide debug banner
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.green),
home: HomePage(),
);
}
}
/// [StatefulWidget] so that we can change
/// internal state to show proper working
/// of [PULL TO REFRESH] feature
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// ScaffoldKey object. This is required
// to show snackbar
// This is optional. This is not required always
late GlobalKey<ScaffoldState> _scaffoldKey;
// Local State to display items in listview
late List<String> _demoData;
// This method will run once widget is loaded
// i.e when widget is mounting
@override
void initState() {
// initializing states
_demoData = [
"Flutter",
"React Native",
"Cordova/ PhoneGap",
"Native Script",
];
_scaffoldKey = GlobalKey();
super.initState();
}
// This method will run when widget is unmounting
@override
void dispose() {
// disposing states
_scaffoldKey?.currentState?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: const Text('GeeksforGeeks'),
backgroundColor: Colors.green,
foregroundColor: Colors.white,
),
// Widget to show RefreshIndicator
body: RefreshIndicator(
child: ListView.builder(
itemBuilder: (ctx, idx) {
// List Item
return Card(child: ListTile(title: Text(_demoData[idx])));
},
// Length of the list
itemCount: _demoData.length,
// To make listView scrollable
// even if there is only a single item.
physics: const AlwaysScrollableScrollPhysics(),
),
// Function that will be called when
// user pulls the ListView downward
onRefresh: () {
return Future.delayed(Duration(seconds: 1), () {
/// adding elements in list after [1 seconds] delay
/// to mimic network call
///
/// Remember: [setState] is necessary so that
/// build method will run again otherwise
/// list will not show all elements
setState(() {
_demoData.addAll(["Ionic", "Xamarin"]);
});
// showing snackbar
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: const Text('Page Refreshed')
)
);
}
);
},
),
),
);
}
}
Note: In some cases, you will notice that the refresh indicator is not showing. To make it visible all the time please use physics: In Flutter all the scrollable widgets have physics properties.
The below will enable scrolling even if there are only a few elements in the list.
ListView(
physics: const AlwaysScrollableScrollPhysics(),
...
)
Output:
Similar Reads
Implementing Rest API in Flutter
Along with building a UI in Flutter, we can also integrate it with the backend. Most applications use APIs to display user data. We will use the http package, which provides advanced methods to perform operations. REST APIs use simple HTTP calls to communicate with JSON data because: It uses await
5 min read
Flutter - Implement map() Method
In Flutter, the map() method is used to transform and manipulate the elements of a collection (such as a List, Set, or Iterable) and produce a new collection with the transformed values. It allows you to apply a function to each element of the collection and create a new collection based on the resu
4 min read
Flutter - Implementing Signing Out the User
In this article, we can learn how to Signout the user from a flutter application. This article is a continuation of the article that explains making google signIn UI and its authentication. It is recommended to check the same before moving ahead. Now we will implement the Sign out feature for the fl
4 min read
Flutter - Implement IndexedStack Widget
The IndexedStack widget in Flutter is used to display a single child from a list of children at a given index. It's commonly used when you want to show one child widget while hiding the others, such as in a tabbed interface. In this article, we are going to implement the IndexedStack widget and expl
5 min read
Implementing Flutter Gauge
Flutter gauge is an information perception widget written in dart language to make a modern, interactive, and animated gauge check and is utilized to make excellent portable application user interfaces utilizing Flutter. There is an alternate style of gauge in flutter. Following are the steps to fol
4 min read
Flutter - Implementing Swipe to Dismiss Feature
The Swipe to dismiss feature is used by us in many mobile apps. In this article, we will create a list of items and implement a swipe to dismiss in it. When we want to dismiss the content using swipe then we can do this with the help of swipe to dismiss widget in a flutter. Generally, we use this wh
2 min read
Flutter - Implementing Badges
Badges can be used for various purposes in an application. For example, showing the number of messages, number of items in the cart, etc. In this article, we will see the implementation of badges in Flutter using the badges Flutter package. Install the library: In the pubspec.yaml file, add badges l
5 min read
How to Install Shared Preferences in Flutter?
Shared preferences in flutter applications are used to store data in Local Storage. Shared Preferences store the data in a key-value pair. and we can also get data in a key-value pair using inbuilt functions. We can save large data in local storage or our Phone storage with the help of SQLite databa
2 min read
Flutter - Implementing Calendar
Nowadays in most of the apps, we see Calendar in most of the apps for displaying birth dates or for any appointment application. Displaying the date in the app with the help of the Calendar view gives a better user experience. In this article, we are going to see how to implement Calendar in our Flu
3 min read
Flutter - State Management Provider
In this article, we are going to learn how state management is achieved in Flutter using providers. But before that, we need to know what a state is. As we know that everything in Flutter is a widget, and there are mainly two kinds of widgets: Stateless Widgets and Stateful Widgets. Stateless widget
8 min read