Implementing Shimmer Effect in Flutter
- Aarthi Krishnan
- May 24, 2024
- 5 min read
Updated: May 24, 2024

Shimmer Effect Flutter Introduction:
Flutter is a powerful framework for creating visually appealing and natively compiled applications for mobile, web, and desktop from a single codebase. One impressive feature that can be incorporated into your Flutter app is the shimmer effect Flutter. This effect serves as a placeholder for your content while it loads, improving the user experience by visually indicating that data is being fetched. In this detailed guide, we will develop a Flutter app that showcases how to implement the shimmer effect in Flutter App, accompanied by a thorough explanation of the code.
Table of Contents
Introduction
Setting Up Flutter
Creating the Flutter App
Adding Dependencies
Building the UI
Implementing the Shimmer Effect Flutter
Displaying the Content
Complete Code Snippet
Conclusion
Before we start writing code, let's ensure that you have Flutter set up on your machine. Follow these steps to get started:
flutter create shimmer_example
In my case i named my project shimmer_example you can give whatever you want. Navigate to the project directory:
cd shimmer_example
Adding Dependencies:
We will use two packages in this project: google_fonts for custom fonts and shimmer for the shimmer effect Flutter. Add these dependencies to your pubspec.yaml file:
dependencies:
flutter:
sdk: flutter
google_fonts: ^3.0.1
shimmer: ^2.0.0
url_launcher: ^6.2.6
Run flutter pub get to install the packages.
Building the UI
Let's start by building the basic UI for our app. We will create a simple list that will display items with a shimmer effect while the content is loading.
Create a new file named list_item.dart in the lib directory:
// list_item.dart
class ListItem {
final String description;
final String url;
final String images;
ListItem({required this.description, required this.url, required this.images});
}
final List<ListItem> items = [
ListItem(
description: 'Permaculture Camping hostel & more',
url: 'https://www.behance.net/gallery/135408901/ALDEA-VENADO',
images: 'assets/Image1.png',
),
// Add more items here
];
Now, create the main app UI in the main.dart file:
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:shimmer/shimmer.dart';
import 'list_item.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
title: Text(
'Shimmer Effect',
style: GoogleFonts.poppins(
fontSize: 20, color: Colors.black, fontWeight: FontWeight.bold),
),
),
body: ShimmerList(),
),
);
}
}
Implementing the Shimmer Effect
Next, we'll create a shimmer effect while the content is loading. We'll simulate a network call by using a delay.
Create a new file named shimmer_list.dart in the lib directory:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
import 'list_item.dart';
class ShimmerList extends StatefulWidget {
@override
_ShimmerListState createState() => _ShimmerListState();
}
class _ShimmerListState extends State<ShimmerList> {
bool _isLoading = true;
@override
void initState() {
super.initState();
// Simulate a network call
Timer(Duration(seconds: 10), () {
setState(() {
_isLoading = false;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: _isLoading ? _buildShimmerList() : _buildContentList(),
);
}
Widget _buildShimmerList() {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
),
height: 120.0,
),
const SizedBox(height: 10.0),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
height: 13.0,
color: Colors.white,
),
const SizedBox(height: 8.0),
Container(
width: double.infinity,
height: 7.0,
color: Colors.white,
),
const SizedBox(height: 8.0),
Container(
height: 7.0,
color: Colors.white,
),
],
),
],
),
),
);
},
);
}
Widget _buildContentList() {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: Color.fromARGB(255, 191, 189, 189).withOpacity(0.2),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
GestureDetector(
onTap: () => _launchURL(item.url),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(5.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Image.asset(
item.images,
),
),
),
),
),
const SizedBox(height: 8.0),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
item.description,
style: GoogleFonts.poppins(
fontSize: 14.0, color: Colors.black),
),
),
],
),
),
),
);
},
);
}
}
Displaying the Content
We need to add a function to launch the URL when an item is clicked. This function can be added to the _ShimmerListState class.
Future<void> _launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Could not launch $url')),
);
}
}
Complete Code Snippet
Here is the complete code for the Flutter app with the shimmer effect:
// main.dart
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:shimmer/shimmer.dart';
import 'list_item.dart';
import 'shimmer_list.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
title: Text(
'Shimmer Effect',
style: GoogleFonts.poppins(
fontSize: 20, color: Colors.black, fontWeight: FontWeight.bold),
),
),
body: ShimmerList(),
),
);
}
}
// list_item.dart
class ListItem {
final String description;
final String url;
final String images;
ListItem({required this.description, required this.url, required this.images});
}
final List<ListItem> items = [
ListItem(
description: 'Permaculture Camping hostel & more',
url: 'https://www.behance.net/gallery/135408901/ALDEA-VENADO',
images: 'assets/Image1.png',
),
ListItem(
description: 'Branding, Redesign & Visual Identity',
url: 'https://www.behance.net/gallery/164870245/Burguer-Ponto',
images: 'assets/Image2.png',
),
ListItem(
images: 'assets/Image3.png',
description: 'Eating meat is a thing to decompress and release emotions.',
url: 'https://www.behance.net/gallery/156524781/Meat-Now-Company',
),
ListItem(
images: 'assets/Image4.png',
description: 'Woohoop is a leading company in customized packaging',
url: 'https://www.behance.net/gallery/197730331/Woohoop',
),
ListItem(
images: 'assets/Image5.png',
description: 'Lorem ipsum is placeholder text commonly used in the graphic',
url: 'https://www.behance.net/gallery/190466121/Hows-Coffee-Packaging-Design',
),
ListItem(
images: 'assets/Image6.png',
description: 'Lorem ipsum is placeholder text commonly used in the graphic',
url: 'https://www.behance.net/gallery/193952673/Design360-Magazine-No105-Award3602023-BEST-100',
),
ListItem(
images: 'assets/Image7.png',
description: 'Lorem ipsum is placeholder text commonly used in the graphic',
url: 'https://www.behance.net/gallery/166243201/Juicy-Fruit',
),
ListItem(
images: 'assets/Image8.png',
description: 'Lorem ipsum is placeholder text commonly used in the graphic',
url: 'https://www.behance.net/gallery/171606499/Outcore',
),
ListItem(
images: 'assets/Image9.png',
description: 'Lorem ipsum is placeholder text commonly used in the graphic',
url: 'https://www.behance.net/gallery/181729429/SNEAKERHEADZ',
),
ListItem(
images: 'assets/Image10.png',
description: 'Lorem ipsum is placeholder text commonly used in the graphic',
url: 'https://www.behance.net/gallery/194723063/Slanted-Special-Issue-GeorgiaArmenia',
),
];
// shimmer_list.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
import 'list_item.dart';
class ShimmerList extends StatefulWidget {
@override
_ShimmerListState createState() => _ShimmerListState();
}
class _ShimmerListState extends State<ShimmerList> {
bool _isLoading = true;
@override
void initState() {
super.initState();
// Simulate a network call
Timer(Duration(seconds: 10), () {
setState(() {
_isLoading = false;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: _isLoading ? _buildShimmerList() : _buildContentList(),
);
}
Widget _buildShimmerList() {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
),
height: 120.0,
),
const SizedBox(height: 10.0),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: double.infinity,
height: 13.0,
color: Colors.white,
),
const SizedBox(height: 8.0),
Container(
width: double.infinity,
height: 7.0,
color: Colors.white,
),
const SizedBox(height: 8.0),
Container(
height: 7.0,
color: Colors.white,
),
],
),
],
),
),
);
},
);
}
Widget _buildContentList() {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: Color.fromARGB(255, 191, 189, 189).withOpacity(0.2),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
GestureDetector(
onTap: () => _launchURL(item.url),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(5.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: Image.asset(
item.images,
),
),
),
),
),
const SizedBox(height: 8.0),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
item.description,
style: GoogleFonts.poppins(
fontSize: 14.0, color: Colors.black),
),
),
],
),
),
),
);
},
);
}
Future<void> _launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Could not launch $url')),
);
}
}
}
PROJECT DEMO VIDEO:
Conclusion:
In this comprehensive guide, we've covered the steps to create a Flutter app with a shimmer effect. This effect enhances the user experience by providing a visual placeholder while content is loading. By following this guide, you'll be able to implement a similar shimmer effect in your own Flutter applications. That's it. This is How we achieve How to Implement shimmer effect flutter in our Flutter App.
Happy coding ❤️
Aarthi Krishnan
Comments