Refresh Page in Flutter – In mobile app development, page refreshes are commonplace. It’s especially helpful for updating frequently-changing dynamic content. The process of Refresh Page in Flutter will be covered in this article. The following are the areas we will discuss:
- In Flutter, what does “RefreshIndicator” mean?
- When to use a RefreshIndicator and how to do so.
- In what ways can a RefreshIndicator be modified?
- Reloading a page with a StreamBuilder: How to Do It?
What is a RefreshIndicator in Flutter?
If you want to Refresh Page in Flutter, you can use the RefreshIndicator widget. The RefreshIndicator displays a loading indicator and triggers a function that refreshes the page or list when the user pulls down on the screen.
How to Refresh Page in Flutter with RefreshIndicator?
Here’s what you need to do to Refresh Page in Flutter with RefreshIndicator:
- Step 1: make a stateful widget to stand in for the page you want to refresh. Create a list or other modifiable data structure in the stateful widget.
- Step 2: Wrap the list or other data structure you want to refresh in a RefreshIndicator widget, which is the second step. The RefreshIndicator widget requires a child widget representing the list or data structure to be refreshed and a onRefresh callback function.
- Step 3: modify the onRefresh callback function to reflect the changes to the data structure or list you intend to refresh. Any asynchronous function can be used to synchronize the data structure or list.
- Step 4: to have the onRefresh callback function return a Future. When the update is done, The Future will be finished.
Example code:
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Refresh Page in Flutter with RefreshIndicator', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Row(children: [ Image.asset( 'assets/logo.png', height: 30, ), Text('flutterflux.com') ]), ), body: MyPage()); } } class MyPage extends StatefulWidget { @override _MyPageState createState() => _MyPageState(); } class _MyPageState extends State<MyPage> { List<String> items = ['Item 1', 'Item 2', 'Item 3']; Future<void> _refresh() async { // Perform some asynchronous operation to update the items list await Future.delayed(Duration(seconds: 1)); setState(() { items.add('New Item'); }); } @override Widget build(BuildContext context) { return Scaffold( body: RefreshIndicator( // Refresh Page in Flutter onRefresh: _refresh, child: ListView.builder( itemCount: items.length, itemBuilder: (BuildContext context, int index) { return ListTile( title: Text(items[index]), ); }, ), ), ); } }
Output
In this example, we’ve built a stateful widget (named MyPage). We store the information we wish to modify in a ListString> named items within the _MyPageState
class. We’ve also codified a _refresh
function, which, when called, appends a new item to the items list.
A RefreshIndicator
widget was used to enclose the ListView.builder
widget in the build
method. We have set the onRefresh
callback to the _refresh
function. When the user pulls down on the screen, the _refresh
function is invoked, and the ListView.builder
widget is refreshed to include the user’s new addition.
How to customize a RefreshIndicator?
To customize a RefreshIndicator to your needs, use the constructor’s parameters. Some of the parameters available for use when modifying a RefreshIndicator are as follows:
color
: The color of the progress indicator.backgroundColor
: The color of the background of the RefreshIndicator.displacement
: The distance that the user needs to pull down the screen before the Refresh Indicator is activated.notificationPredicate
: A function that determines whether a scroll notification should trigger the RefreshIndicator. By default, the RefreshIndicator is triggered when the user scrolls down the screen and releases it.semanticsLabel
: The label used by screen readers to describe the RefreshIndicator.semanticsValue
: The value used by screen readers to describe the RefreshIndicator.
Example code:
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Refresh Page in Flutter with RefreshIndicator', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Row(children: [ Image.asset( 'assets/logo.png', height: 30, ), Text('flutterflux.com') ]), ), body: MyPage()); } } class MyPage extends StatefulWidget { @override _MyPageState createState() => _MyPageState(); } class _MyPageState extends State<MyPage> { List<String> items = ['Item 1', 'Item 2', 'Item 3']; Future<void> _refresh() async { // Perform some asynchronous operation to update the items list await Future.delayed(Duration(seconds: 1)); setState(() { items.add('New Item'); }); } @override Widget build(BuildContext context) { return Scaffold( body: RefreshIndicator(// Refresh Page in Flutter backgroundColor: Colors.black, color: Colors.black, displacement: 50.0, notificationPredicate: (ScrollNotification notification) { return notification.metrics.pixels >= notification.metrics.maxScrollExtent / 2; }, semanticsLabel: 'Pull to refresh', semanticsValue: 'Refresh', onRefresh: _refresh, child: ListView.builder( itemCount: items.length, itemBuilder: (BuildContext context, int index) { return ListTile( title: Text(items[index]), ); }, ), ), ); } }
Output
We’ve modified the RefreshIndicator
in this case by changing its backgroundColor
to Colors.blueGrey
, color to Colors.white
, displacement to 50.0
, notificationPredicate to cause a refresh when the user scrolls down to the page’s midpoint, and semanticsLabel
and semanticsValue
to make it more accessible.
How to Reload Page with StreamBuilder?
A StreamBuilder can be used to automatically Refresh Page in Flutter whenever the data stream changes.
Listed below is some sample code:
import 'dart:async'; import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Hide FloatingActionButton in Flutter', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Row(children: [ Image.asset( 'assets/logo.png', height: 30, ), Text('flutterflux.com') ]), ), body: MyPage()); } } class MyPage extends StatefulWidget { @override _MyPageState createState() => _MyPageState(); } class _MyPageState extends State<MyPage> { StreamController<List<String>> _streamController = StreamController<List<String>>(); void _loadData() { List<String> items = ['Item 1', 'Item 2', 'Item 3']; _streamController.add(items); // Perform some asynchronous operation to update the items list Future.delayed(Duration(seconds: 1)).then((value) { items.add('New Item'); _streamController.add(items); }); } @override void initState() { super.initState(); _loadData(); } @override void dispose() { _streamController.close(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: StreamBuilder( stream: _streamController.stream, builder: (BuildContext context, AsyncSnapshot<List<String>> snapshot) { if (snapshot.hasData) { return RefreshIndicator(// Refresh Page in Flutter onRefresh: () async { _loadData(); }, child: ListView.builder( itemCount: snapshot.data!.length, itemBuilder: (BuildContext context, int index) { return ListTile( title: Text(snapshot.data![index]), ); }, )); } else { return Center(child: CircularProgressIndicator()); } }, ), ); } }
Output
Here, a StreamController
is used to send data to a StreamBuilder in a continuous stream. With the help of the _streamController.add
method, the _loadData
function keeps the items list current. The StreamBuilder monitors the stream for new data and updates the widget tree accordingly.
When the user pulls down on the Refresh Page in Flutter, the RefreshIndicator around the ListView.builder
is invoked. When the items list needs to be refreshed and sent to the stream, the _loadData
function is invoked.
Conclusion
In this article, we examined How to Refresh Page in Flutter options. We’ve seen how to use a RefreshIndicator
to pull down and refresh the page, a FutureBuilder
to refresh after an asynchronous operation, and a StreamBuilder to refresh after a stream of data is updated.
We’ve also seen how to customize the RefreshIndicator by changing its background color, loading indicator color, displacement, and semanticsLabel
and semanticsValue
. read too How to Customize AppBar Color in Flutter