Open In App

Flutter – Shimmer

Last Updated : 28 Oct, 2020
Improve
Improve
Like Article
Like
Save
Share
Report

In Flutter, Shimmer is used to add beautiful animations while content is loading from the servers in an application. This makes the UI look more responsive and secures users from leaving a slow internet interaction. It can be used instead of conventional ProgressBar or usual loaders available in the Flutter framework.

In this article, we will look into its implementation by building a simple application. to do so follow the below steps:

  • Add the dependency in the pubspec.yaml file
  • Import the dependency in the main.dart file
  • Use StatefulWidget to structure the application
  • Add a loading screen, that doesn’t load to show the shimmer effect

Let’s look into the steps in detail.

Adding the Dependency:

To add the dependency to the pubspec.yaml file, add shimmer as a dependency in the dependencies part of the pubspec.yaml file as shown below:

dependency

Importing the Dependency:

Use the below line of code in the main.dart file, to import the shimmer dependency :

import 'package:shimmer/shimmer.dart';

Structuring the Application:

A StatefulWidget can be extended to create an appbar and a body. This is the homepage that will further navigate to a loading screen on the click of a button. The loading screen will have a shimmer representation. to do so follow the below:

Dart




class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GeeksForGeeks',
      routes: {
        'loading': (_) => LoadingListPage(),
      },
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: MyHomePage(),
    );
  }
}
  
class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
  
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Shimmer'),
        backgroundColor: Colors.green,
      ),
      body: Column(
        children: [
          ListTile(
            title: const Text('Loading List'),
            onTap: () => Navigator.of(context).pushNamed('loading'),
          ),
        ],
      ),
    );
  }
}


Creating the Loading Screen:

The loading screen will be an extension of the StatefulWidget. Inside the body of the loading screen, it’s children will have the columns on which the shimmers effect will be implemented as shown below:

Dart




Shimmer.fromColors(
                baseColor: Colors.grey[300],
                highlightColor: Colors.grey[100],
                enabled: _enabled,
                child: ListView.builder(
                  itemBuilder: (_, __) => Padding(
                    padding: const EdgeInsets.only(bottom: 8.0),
                    child: Row(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: 
                        )
                      ],
                    ),
                  ),
                  itemCount: 6,
                ),


Complete Source Code:

Dart




import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
  
void main() => runApp(MyApp());
  
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GeeksForGeeks',
      routes: {
        'loading': (_) => LoadingListPage(),
      },
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: MyHomePage(),
    );
  }
}
  
class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
  
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Shimmer'),
        backgroundColor: Colors.green,
      ),
      body: Column(
        children: [
          ListTile(
            title: const Text('Loading List'),
            onTap: () => Navigator.of(context).pushNamed('loading'),
          ),
        ],
      ),
    );
  }
}
  
class LoadingListPage extends StatefulWidget {
  @override
  _LoadingListPageState createState() => _LoadingListPageState();
}
  
class _LoadingListPageState extends State<LoadingListPage> {
  bool _enabled = true;
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Loading List'),
      ),
      body: Container(
        width: double.infinity,
        padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0),
        child: Column(
          mainAxisSize: MainAxisSize.max,
          children: <Widget>[
            Expanded(
              child: Shimmer.fromColors(
                baseColor: Colors.grey[300],
                highlightColor: Colors.grey[100],
                enabled: _enabled,
                child: ListView.builder(
                  itemBuilder: (_, __) => Padding(
                    padding: const EdgeInsets.only(bottom: 8.0),
                    child: Row(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Container(
                          width: 48.0,
                          height: 48.0,
                          color: Colors.white,
                        ),
                        const Padding(
                          padding: EdgeInsets.symmetric(horizontal: 8.0),
                        ),
                        Expanded(
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: <Widget>[
                              Container(
                                width: double.infinity,
                                height: 8.0,
                                color: Colors.white,
                              ),
                              const Padding(
                                padding: EdgeInsets.symmetric(vertical: 2.0),
                              ),
                              Container(
                                width: double.infinity,
                                height: 8.0,
                                color: Colors.white,
                              ),
                              const Padding(
                                padding: EdgeInsets.symmetric(vertical: 2.0),
                              ),
                              Container(
                                width: 40.0,
                                height: 8.0,
                                color: Colors.white,
                              ),
                            ],
                          ),
                        )
                      ],
                    ),
                  ),
                  itemCount: 6,
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 8.0),
              child: FlatButton(
                  onPressed: () {
                    setState(() {
                      _enabled = !_enabled;
                    });
                  },
                  child: Text(
                    _enabled ? 'Stop' : 'Play',
                    style: Theme.of(context).textTheme.button.copyWith(
                        fontSize: 18.0,
                        color: _enabled ? Colors.redAccent : Colors.green),
                  )),
            )
          ],
        ),
      ),
    );
  }
}


Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads