DEV Community

Nabin Dhakal
Nabin Dhakal

Posted on

Shimmer Loading with Provider

This article will help you to get started with shimmer effect when loading with state management using provider. The final app looks as follows:

Image description

Provider

Provider is built by the community for the effective state management. Although it is not developed by google, it encourages to use it. It is easier to use and manage which is basically a wrapper around the Inherited Widgets.

Shimmer

Shimmer is loading effect that is used to add beautiful animation when the data is loading from server. In simple words, it is the loader like Circular Progress Indicator available in the Flutter framework.

Let’s Dig In

First of all, put all these dependencies in your pubsec.yaml
shimmer: ^2.0.0
provider: ^6.0.3
http: ^0.13.4

First create a New Flutter Project and run your example app. Then create a new folder named response inside the lib folder . Inside the response folder create the new dart file named response_data.dart. Here we will create the model for our api. We are getting test api from this link.

response_data.dart

class ResponseData {
int? page;
int? perPage;
int? total;
int? totalPages;
List<Data>? data;
Support? support;
ResponseData(
{this.page,
this.perPage,
this.total,
this.totalPages,
this.data,
this.support});
ResponseData.fromJson(Map<String, dynamic> json) {
page = json['page'];
perPage = json['per_page'];
total = json['total'];
totalPages = json['total_pages'];
if (json['data'] != null) {
data = <Data>[];
json['data'].forEach((v) {
data!.add(new Data.fromJson(v));
});
}
support =
json['support'] != null ? new Support.fromJson(json['support']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['page'] = this.page;
data['per_page'] = this.perPage;
data['total'] = this.total;
data['total_pages'] = this.totalPages;
if (this.data != null) {
data['data'] = this.data!.map((v) => v.toJson()).toList();
}
if (this.support != null) {
data['support'] = this.support!.toJson();
}
return data;
}
}
class Data {
int? id;
String? email;
String? firstName;
String? lastName;
String? avatar;
Data({this.id, this.email, this.firstName, this.lastName, this.avatar});
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
email = json['email'];
firstName = json['first_name'];
lastName = json['last_name'];
avatar = json['avatar'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['email'] = this.email;
data['first_name'] = this.firstName;
data['last_name'] = this.lastName;
data['avatar'] = this.avatar;
return data;
}
}
class Support {
String? url;
String? text;
Support({this.url, this.text});
Support.fromJson(Map<String, dynamic> json) {
url = json['url'];
text = json['text'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['url'] = this.url;
data['text'] = this.text;
return data;
}
}

Then we will create a provider class where we fetch the api.

getdata_provider.dart

import 'dart:developer';
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:shimmer_example/response/response_data.dart';
import 'package:http/http.dart' as http;
class GetDataProvider with ChangeNotifier {
ResponseData responseData = ResponseData();
bool isLoading = false;
getMyData() async {
isLoading = true;
responseData = await getAllData();
isLoading = false;
notifyListeners();
}
Future<ResponseData> getAllData() async {
try {
final response = await http
.get(Uri.parse("https://reqres.in/api/users?page=2"));
if (response.statusCode == 200) {
final item = json.decode(response.body);
responseData = ResponseData.fromJson(item);
notifyListeners();
} else {
print("else");
}
} catch (e) {
log(e.toString());
}
return responseData;
}
}

Then, we create the widget that includes how our shimmer layout gonna be.

shimmer_layout.dart

import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
Widget loadingShimmer() => Shimmer.fromColors(
baseColor: Colors.grey,
highlightColor: Colors.grey[400]!,
period:const Duration(seconds: 1),
child: Container(
decoration: BoxDecoration(border: Border.all(color: Colors.grey)),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Expanded(
flex: 1,
child: Container(
width: 100,
height: 100,
color: Colors.grey,
),
),
const SizedBox(
width: 10,
),
Expanded(
flex: 3,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 250,
height: 10,
color: Colors.grey,
),
const SizedBox(
height: 10,
),
Container(
width: 150,
height: 10,
color: Colors.grey,
),
],
),
)
],
),
),
);

Finally we will create the Homepage.

homepage.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shimmer_example/provider/getdata_provider.dart';
import 'package:shimmer_example/utils/shimmer_layout.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
void initState() {
super.initState();
final dataProvider = Provider.of<GetDataProvider>(context, listen: false);
dataProvider.getMyData();
}
@override
Widget build(BuildContext context) {
final dataProvider = Provider.of<GetDataProvider>(context);
return Scaffold(
appBar: AppBar(
title: const Text("Shimmer Effect"),
),
body: dataProvider.isLoading
? Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: 10,
itemBuilder: (ctx,i){
return Column(
children: [
loadingShimmer(),
const SizedBox(height: 10,)
],
);
}),
)
: ListView.builder(
shrinkWrap: true,
itemCount: dataProvider.responseData.data!.length,
itemBuilder: (ctx, i) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Image.network(dataProvider.responseData.data![i].avatar!,height:100,width: 100,fit: BoxFit.cover,),
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(dataProvider.responseData.data![i].firstName!),
const SizedBox(height: 10,),
Text(dataProvider.responseData.data![i].email!),
],
),
),
],
)),
);
}),
);
}
}
view raw homepage.dart hosted with ❤ by GitHub

At last our main.dart file.

main.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shimmer_example/provider/getdata_provider.dart';
import 'homepage.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (ctx) => GetDataProvider()),
],
child:const MaterialApp(
title: 'Flutter Demo',
home: HomePage(),
));
}
}
view raw main.dart hosted with ❤ by GitHub

Lets get connected

We can friends. Find in Facebook, Linkedin, Github, Instagram, Medium.

Conclusion

I hope this article is helpful to you and you learned new things. I have used various things in this article that might be new for some of you.

If you learned something new or want to suggest something then please let me know in the comment.

If you loved the article click on icon which provides motivation on delivering you all with the new things.

Also follow to get updated on exciting articles and projects.

Learning by sharing gives great impact in learning process and making the community bigger and bigger.

Sharing is a magnet that attracts other enthusiast towards you.

Hence, lets take a small step on making our learning community bigger.

Share this article with your friends or tweet about this article if you loved it.

Get Full code at




Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read more →

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more