I have this code that has the parent widget Homepage
and the child widget CountryList
. In CountryList
, I have created a function that uses an API to get a list of countries. I felt like enabling a RefreshIndicator
in the app, so I had to modify the Homepage
widget and add GlobalKey
to access getCountryData()
function of CountryList
widget. The RefreshIndicator
has done its job well. But the problem now is that when I pull and use the RefreshIndicator
in the app, the getCountryData()
function is called, but even after showing all data in the list, the circular spinner doesn't go (shown in the screenshot).
So, could anyone please suggest me a way to make the spinner go?
The code of main.dart
containing Homepage
widget is given below:
import 'package:flutter/material.dart';
import 'country_list.dart';
GlobalKey<dynamic> globalKey = GlobalKey();
void main() => runApp(MaterialApp(home: Homepage()));
class Homepage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("List of countries"), actions: <Widget>[
IconButton(icon: Icon(Icons.favorite), onPressed: (){},)
],),
body: RefreshIndicator(child: CountryList(key:globalKey), onRefresh: (){globalKey.currentState.getCountryData();},),
);
}
}
And the code of country_list.dart
containing CountryList
widget is:
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:flutter_svg/flutter_svg.dart';
class CountryList extends StatefulWidget {
CountryList({Key key}) : super(key: key);
@override
_CountryListState createState() => _CountryListState();
}
class _CountryListState extends State<CountryList> {
List<dynamic> _countryData;
bool _loading = false;
@override
void initState() {
// TODO: implement initState
super.initState();
this.getCountryData();
}
Future<String> getCountryData() async {
setState(() {
_loading = true;
});
var response =
await http.get(Uri.encodeFull("https://restcountries.eu/rest/v2/all"));
var decodedResponse = json.decode(response.body);
setState(() {
_countryData = decodedResponse;
_loading = false;
});
}
@override
Widget build(BuildContext context) {
return _loading?Center(child: Column(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[CircularProgressIndicator(), Padding(padding: EdgeInsets.all(5.0),), Text("Loading data...", style: TextStyle(fontSize: 20.0),)],)):ListView.builder(
itemCount: _countryData.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: ListTile(
leading: SvgPicture.network(_countryData[index]['flag'], width: 60.0,),
title: Text(_countryData[index]['name']),
trailing: IconButton(
icon: Icon(Icons.favorite_border),
onPressed: () {},
),
),
);
},
);
}
}
To disable RefreshIndicator pass notificationPredicate function that returns false.
RefreshIndicator will trigger a refresh when the list is over-scrolled. It is showing a circular progress indicator if you want something to happen, add a callback function with the onRefrence property. This function is not given any parameters, but RefreshIndicator expects it to return a future.
Pull to refresh (swipe to refresh) feature can be implemented in flutter using RefreshIndicator widget. Pull (swipe) to refresh feature lets the user refresh current data or fetch updated data from the server by pulling down on a list.
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, I think you should return Future<String>
from getCountryData
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With