I am creating a simple demo fetching json data.
I've used a Tab bar in my Homepage screen with 3 tabs: one for users, one for todos.
Everything is working well but when I want a little change...on tapping tab it's showing a CircularProgressbar each and everything because I am fetching data with Future function and a FutureBuilder
.
What I would like to achieve is: it should show the CircularProgressbar only the first time, then data should be copied into a local array so that the next time this local data will be shown to avoid loading with the CircularProgressIndicator.
Here is my code:
Future<List<User>> getuserlist() async
{
List<User> userlist=[];
final response=await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
final jsondata=json.decode(response.body);
userlist.clear();
for(var data in jsondata)
{
userlist.add(User.fromJson(data));
}
return userlist;
}
here is screen's body code
FutureBuilder(
future: getuserlist(),
builder: (context,AsyncSnapshot snapshot){
if(snapshot.connectionState==ConnectionState.waiting)
{
return Center(child: CircularProgressIndicator());
}
else
{
if(snapshot.connectionState==ConnectionState.active || snapshot.connectionState==ConnectionState.done)
{
if(snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context,index){
User user=snapshot.data[index];
return ListTile(
title: Text(user.name.toString()),
subtitle: Text(user.email.toString()),
leading: CircleAvatar(child: Text(user.id.toString()),),
);
});
}
else
{
if(snapshot.hasError)
{
return Text('Error found');
}
else
{
return Text('No error no data...');
}
}
}
else
{
return Text('Something wrong');
}
}
},
),
CodePudding user response:
If you want cache data when user close and reopen the app, You can use shared_preferences, to cache the data like this:
Future<List<User>> getuserlist() async
{
List<User> userlist=[];
List jsondata=[];
final prefs = await SharedPreferences.getInstance();
await prefs.reload();
String responsePrefs = prefs.getString(key);
if(responsePrefs != null){
jsondata = json.decode(responsePrefs);
}else {
final response=await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
final prefs = await SharedPreferences.getInstance();
await prefs.reload();
prefs.setString('response', response.body);
jsondata = json.decode(response.body);
}
userlist.clear();
for(var data in jsondata)
{
userlist.add(User.fromJson(data));
}
return userlist;
}
But if you want cache data just for switching between pages, you can do this:
first create singleton class like this:
class GlobalVariable extends ChangeNotifier {
static GlobalVariable? _instance;
factory GlobalVariable() => _instance ??= new GlobalVariable._();
GlobalVariable._();
List<User> _users = [];
setUsers(List<User> user) {
_users = user;
}
List<User> getUsers() {
return _users;
}
}
then change your getuserlist()
to this:
Future<List<User>> getuserlist() async
{
List<User> userlist=[];
if(GlobalVariable().getUsers().isEmpty){
final response=await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
final jsondata=json.decode(response.body);
userlist.clear();
for(var data in jsondata)
{
userlist.add(User.fromJson(data));
}
return userlist;
}else{
return GlobalVariable().getUsers();
}
}