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




AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay