How to Create Shimmer Loading Effect in Flutter

Have you ever filled login form of a mobile application, and you there was no on-screen change after clicking login button, assumed there was a glitch somewhere and kept re-tapping on the login button?

Or, have you ever been confusingly waited for an app to load some data not knowing it’s loading or crashing?

Or, have you ever submitted a form, and saw a graphical pop-up showing you that your request was being processed? and then another message pops up to inform you that your request was either successful or not?

These were common cases of using and not using progress indicators to show users  status of their actions. Apparently, not using progress indications in mobile apps may cause users to assume there is a glitch somewhere and keep re-trying and tapping buttons unnecessarily creating too many requests that puts the app under unneeded pressure causing it to crash in the end.

Using progress indications in mobile apps affects your application’s user experience. Loading time in applications is unavoidable and can be boring, too! From user experience perspective, providing the user with action status and feedback is quite necessary. In this shimmer example post, we’ll discuss how to create shimmer loading effect in Flutter. We’ll together create a shimmer loading effect for posts list that displays posts picture, title, and author name.

What is Shimmer effect?

Shimmer is a loading indicator that’s used to show shimmer animation when data is being fetched from a data source. It paints a shimmer animation that approximately looks like the content that is loading. This way, the UI looks more responsive and users can see that data is loading instead of thinking something went wrong.

In comparison with classic circular and linear progress indicators, shimmer indicator provides a more realistic and aesthetic view to the user as it draws a view that’s similar to the actual one.

 

Implementation

First, add shimmer dependency to pubspec.yaml file:

flutter pub add shimmer

Next, import the shimmer library in the dart file where you’ll create the shimmer

import 'package:shimmer/shimmer.dart';

Now, run flutter get command in the project’s terminal

flutter pub get

The project’s now set, let’s implement the shimmer in our app.

Let’s start by creating a post model class called post_model.dart. In this class, we’ll create 3 final strings: urlImg, title, and author. In addition, we’ll create a constructor for all strings we created.

class PostModel {
   final String urlImg;
   final String title;
   final String author;

  const PostModel({required this.urlImg, required this.title, required this.author});
  
}

Then, let’s create another file called posts_data.dart to store the posts data. Inside this file, we’ll create a list of posts where we’ll add 5 data of PostModel by adding image link, title, and author name of each post.

List<PostModel> allPosts = [
  PostModel(
    urlImg: 'https://daniasblog.com/wp-content/uploads/2022/11/a-rating-dialog-in-flutter-1.png',
    title: 'How to create rating dialog in flutter',
    author: 'Dania\s Blog'
  ),
  PostModel(
      urlImg: 'https://daniasblog.com/wp-content/uploads/2022/11/rating-bar-in-flutter-1.png',
      title: 'How to create rating Bar in flutter',
      author: 'Dania\s Blog'
  ),
  PostModel(
      urlImg: 'https://daniasblog.com/wp-content/uploads/2022/11/Untitled-design.png',
      title: 'How to create animated splash screen in flutter',
      author: 'Dania\s Blog'
  ),
  PostModel(
      urlImg: 'https://daniasblog.com/wp-content/uploads/2022/10/Firebase-storage-in-flutter.png',
      title: 'Firebase storage in Flutter',
      author: 'Dania\s Blog'
  ),
  PostModel(
      urlImg: 'https://daniasblog.com/wp-content/uploads/2022/11/1.png',
      title: 'Splash Screen Flutter Tutorial',
      author: 'Dania\'s Blog'
  ),
];

Now let’s create a new file called posts_page.dart with a stateful widget. The first thing we need to do in this file is creating a method called buildPostList that creates the posts list

Widget buildPostList(List<PostModel> model) {
  return ListView.builder(
      itemCount: model.length,
      itemBuilder: (_, int index) {
        return Padding(
          padding: const EdgeInsets.only(bottom: 10),
          child: Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Container(
                width: 60,
                height: 60,
                child: Image.network(model[index].urlImg),
              ),
              const Padding(
                padding: EdgeInsets.symmetric(horizontal: 8),
              ),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Container(
                      width: double.infinity,
                      child: Text(
                        model[index].title,
                        style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 18,
                            color: Colors.deepPurple),
                      ),
                    ),
                    const Padding(
                      padding: EdgeInsets.symmetric(vertical: 2),
                    ),
                    Container(
                      child: Text(
                        model[index].author,
                        style: TextStyle(
                            fontWeight: FontWeight.bold, fontSize: 14),
                      ),
                    )],
                ),
              )],
          ),
        );
      });
}

After that, we’ll create another method to build the post shimmer

Widget buildPostShimmer() {
  return Shimmer.fromColors(
      baseColor: Colors.blue.shade200,
      highlightColor: Colors.blue.shade100,
      child: ListView.builder(
          itemCount: 5,
          itemBuilder: (_, __) => Padding(
            padding: const EdgeInsets.only(bottom: 10),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Container(
                  width: 60,
                  height: 60,
                  color: Colors.blue,
                ),
                const Padding(
                  padding: EdgeInsets.symmetric(horizontal: 8),
                ),
                Expanded(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Container(
                        width: double.infinity,
                        height: 12,
                        color: Colors.blue,
                      ),
                      const Padding(
                        padding: EdgeInsets.symmetric(vertical: 2),
                      ),
                      Container(
                        width: 60,
                        height: 12,
                        color: Colors.blue,
                      )
                    ],
                  ),
                )
              ],
            ),
          )));
}

Notice that the post list and shimmer have the same layout structure. This makes the shimmer effect more realistic and closer to the actual UI.

Let’s now create two variables: isLoading to indicate when data loading is happening and posts to store the posts data

List<PostModel> posts = [];
bool isLoading = false;

Next, we’ll create a new method laodData() that triggers the beginning of loading the data.

Future loadData() async {
  setState(() {
    isLoading = true;
  });
  await Future.delayed(Duration(seconds: 2));
  posts = List.of(allPosts);
  setState(() {
    isLoading = false;
  });
}

Now, let’s override the initState method to call loadData() in it

@override
void initState() {
  // TODO: implement initState
  super.initState();
  loadData();
}

Now it’s time to do the final steps in the UI inside the build method. Based on the value of the variable isLoading, either posts list or post shimmer will be displayed

return Scaffold(
  appBar: AppBar(
    title: const Text('Shimmer Example'),
    centerTitle: true,
  ),
  body: Container(
    width: double.infinity,
    padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
    child: isLoading ? buildPostShimmer() : buildPostList(posts),
  ),
);

And that’s it, your shimmer loading effect is ready!

Conclusion

The user experience that progress indicators add to your app is priceless. You never want to leave your users confused and wondering if there’s a glitch in your application each time they perform an action and there is no appropriate indication about the status of their request. This will guarantee your users that they’re doing the right steps to perform a specific action and everything is running well.

In this shimmer example, we learnt how loading effect is implemented. Shimmer loading animation influences user experience in a way that the user knows well what’s going in there.

I hope this post I was able to guide you how to implement shimmer loading animation in flutter application.

Please don’t hesitate to support this blog with a like and share if you find its content useful. If you wish to learn more about Flutter programming, you can access a whole Flutter category with plenty of useful topics related to it.

Also, don’t forget to like and share my Facebook page, share the post with those who care to learn, and subscribe to my blog to be one of the firsts to know about my newest posts!

Thank you and happy coding!

Oh hi there!
It’s nice to meet you.

Sign up to receive awesome content in your inbox, every month.

Let's Do This!

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top