Creating Stunning Shimmer Loadings in Flutter like a Pro

Muhamad Zulfa Assyfa
4 min readFeb 20, 2023

--

In today’s fast-paced world, people expect their mobile applications to be both visually appealing and user-friendly. One of the ways to enhance the user experience is by adding shimmer loadings to your application. Shimmer loading animations are commonly used as a placeholder for data that hasn’t loaded yet. In this article, we will explore how to create stunning shimmer loadings in Flutter like a pro.

We will be using the JSONPlaceholder API for this tutorial. JSONPlaceholder is a free online REST API that provides fake data for testing and prototyping. We will be using the photos endpoint of the API, which returns a list of photos in JSON format.

What are shimmer loadings?

Shimmer loadings are a type of loading animation that mimics the shimmering effect of light on a surface. Shimmer loadings are commonly used to indicate that data is being loaded, and they provide a more visually appealing alternative to the traditional spinner or progress bar.

To create a shimmer loading animation in Flutter, we will be using the Shimmer package, which provides an easy-to-use widget for creating shimmering effects.

First, let’s create a new Flutter project and add the Shimmer package to our project’s dependencies. We can do this by adding the following line to our pubspec.yaml file:

dependencies:
shimmer: ^2.0.0
http: ^0.13.5

Next, we will create a new Dart file and import the necessary packages:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:shimmer/shimmer.dart';
import 'package:shimmer_loading/model/photo_model.dart';

In this example, we are importing the material.dart library from the Flutter SDK, the http.dart library for making HTTP requests, the shimmer.dart library from the Shimmer package for creating shimmer effects, and a custom photo_model.dart file that we will use to parse the JSON response from the API.

Let’s create a new MyHomePage widget that will be the main widget of our application. This widget will display a list of photos retrieved from the API. If the API call is still in progress, we will display a shimmer loading animation instead.

class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key});

@override
State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
List<PhotoModel> photoModel = [];

getPhotoFromApi() async {
var url = "https://jsonplaceholder.typicode.com/photos";
final response = await get(Uri.parse(url));
if (response.statusCode == 200) {
List<dynamic> responseData = jsonDecode(response.body);
List<PhotoModel> photos =
responseData.map((data) => PhotoModel.fromJson(data)).toList();
setState(() {
photoModel = photos;
});
} else {
SnackBar(content: Text(response.body));
}
}

@override
void initState() {
super.initState();
getPhotoFromApi();
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: photoModel.length > 0
? ListView.builder(
itemCount: photoModel.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.transparent,
child: Image.network(photoModel[index].url!)),
title: Text(photoModel[index].title!),
),
);
})
: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: ListView.builder(
itemCount: 50,
shrinkWrap: true,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Card(
child: Container(
width: 50,
height: 50,
),
),
Card(
child: Container(
width: 300,
height: 50,
),
),
],
),
);
},
),
),
);
}
}

In this widget, we define a list of PhotoModel objects called photoModel, which will store the photos retrieved from the API. We then define an asynchronous function called getPhotoFromApi that retrieves the photos from the API and stores them in the photoModel list.

We call the getPhotoFromApi function in the `init method to retrieve the photos when the widget is first created.

In the build method, we check if the photoModel list is not empty, and if it’s not, we display a ListView of photos. Each photo is displayed as a ListTile with the photo’s title and thumbnail. If the photoModel list is empty, we display a shimmer loading animation using the Shimmer.fromColors widget from the Shimmer package.

The Shimmer.fromColors widget creates a shimmering effect with two colors: baseColor and highlightColor. The child of the Shimmer.fromColors widget is a ListView.builder that displays 50 placeholder items with a Card and two Containers in a Row. The width and height of the Containers are set to create a specific layout.

That’s it! With just a few lines of code, we have created a shimmer loading animation in Flutter using the Shimmer package. This can help improve the user experience of our application by providing visual feedback that data is being loaded.

In conclusion, the Shimmer package is a great tool for creating shimmer loading animations in Flutter. It provides an easy-to-use widget that can be customized to create subtle, yet effective shimmer effects that can help improve the user experience of our applications.

In this example, we used the Shimmer package to create a shimmer loading animation for a list of photos retrieved from an API. We also used the http.dart library to make the API request and a custom PhotoModel class to parse the JSON response.

By implementing a shimmer loading animation, we can provide visual feedback to our users that data is being loaded and avoid leaving them waiting in uncertainty. This can make our application feel more responsive and improve the overall user experience.

I hope you found this example helpful in understanding how to use the Shimmer package in Flutter. Thank you for reading, and happy coding!

--

--