Flutter Skeleton Loader

Flutter Skeleton Loader

Table of contents

No heading

No headings in the article.

Loading times are unavoidable in application development. From a user experience (UX) perspective, the most important thing is to show your users that loading is taking place. One popular approach to communicate to users that data is loading is to display a chrome color with a shimmer animation over the shapes that approximate the type of content that is loading.

Have you ever wondered how apps like Slack, Facebook, Netflix, Linkedin, etc. show their loading page while fetching data?

Flutter has a package that takes care of the loading skeleton. The name of the package is Shimmer

Below is the Basic Implementation of installing and using this package -

Installation steps -

  1. Run this command on your terminal:

    flutter pub add shimmer

    or add this to your package’s pubspec.yaml file:

    dependencies: shimmer: ^2.0.0

  2. Install packages from the command line with Flutter:

    flutter pub get

  3. Now in your Dart code, you can use:

    import ‘package:shimmer/shimmer.dart’;

One thing you need to know when building a skeleton for your flutter app is that it should take the same structure as what the widget will look like after fetching the data. An example is if your widget is a circle avatar, the skeleton should be in a circle form.

CircleAvatar(
        backgroundColor: Colors.greenAccent[400],
            radius: 50,
            child: Text(
              'Hello',
              style: TextStyle(fontSize: 25, color: Colors.white),
            ), //Text
          ),

Your skeleton can look like this:

Container(
              height: 50,
              width: 50
              decoration: BoxDecoration(
                borderRadius: BorderRadius.all(Radius.circular(50)),
                color: Colors.white,
              ),
            ),

Now let's try an example of what shimmer looks like.

Assuming your UI looks like this:

Screenshot 2022-10-14 at 08.40.50.png

Now let's use shimmer to build the skeleton.

import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Skeleton',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Skeleton'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);


  final String title;

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

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: SizedBox(
          width: 500.0,
          height: 100.0,
          child: Shimmer.fromColors(
            baseColor: Colors.grey[300]!,
            highlightColor: Colors.grey[100]!,
            child: Padding(
              padding: const EdgeInsets.symmetric(horizontal: 20),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Column(
                    children: [
                      Container(
                        height: 70,
                        width: 70,
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.all(Radius.circular(50)),
                          color: Colors.white,
                        ),
                        // color: Colors.white,
                      ),

                      SizedBox(
                        height: 10,
                      ),

                      Column(
                          children: [
                            Container(
                              width: 50,
                              height: 14.0,
                              color: Colors.white,

                            ),
                          ]),
                    ],
                  ),

                  Column(
                    children: [
                      Container(
                        height: 70,
                        width: 70,
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.all(Radius.circular(50)),
                          color: Colors.white,
                        ),
                        // color: Colors.white,
                      ),

                      SizedBox(
                        height: 10,
                      ),

                      Column(
                          children: [
                            Container(
                              width: 50,
                              height: 14.0,
                              color: Colors.white,

                            ),
                          ]),
                    ],
                  ),

                  Column(
                    children: [
                      Container(
                        height: 70,
                        width: 70,
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.all(Radius.circular(50)),
                          color: Colors.white,
                        ),
                        // color: Colors.white,
                      ),

                      SizedBox(
                        height: 10,
                      ),

                      Column(
                          children: [
                            Container(
                              width: 50,
                              height: 14.0,
                              color: Colors.white,

                            ),
                          ]),
                    ],
                  ),

                  Column(
                    children: [
                      Container(
                        height: 70,
                        width: 70,
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.all(Radius.circular(50)),
                          color: Colors.white,
                        ),
                        // color: Colors.white,
                      ),

                      SizedBox(
                        height: 10,
                      ),

                      Column(
                          children: [
                            Container(
                              width: 50,
                              height: 14.0,
                              color: Colors.white,

                            ),
                          ]),
                    ],
                  ),

                  Column(
                    children: [
                      Container(
                        height: 70,
                        width: 70,
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.all(Radius.circular(50)),
                          color: Colors.white,
                        ),
                        // color: Colors.white,
                      ),

                      SizedBox(
                        height: 10,
                      ),

                      Column(
                          children: [
                            Container(
                              width: 50,
                              height: 14.0,
                              color: Colors.white,

                            ),
                          ]),
                    ],
                  ),
                ],
              ),
            ),
          )
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){},
        child: const Icon(Icons.add),
      ), 
    );
  }
}
  • You can see the container has a box decoration with border radius, to give it a rounded shape from the UI.

Here's the output:

Screenshot 2022-10-14 at 09.00.00.png

You can always customize your shimmer code to fit into whatever UI you may be working with.