How to Add Preloader to Image in Flutter
Tags: flutter, webdev, codenewbie
Published: 2020-12-24 13:05:24

---
title: How to Add  Preloader to Image in Flutter
published: true
description:
tags: flutter, webdev, codenewbie
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/7yxrz3fxlke057sai32y.png
canonical_url: https://daily.dev/posts/how-to-add-preloader-to-image-in-flutter
---

Flutter is a cross-platform mobile application development framework that offers a widget-based mechanism to implement the pixel-perfect UI. Creating a state of the art apps with beautiful UI is a challenge for every mobile app developer. And, Flutter has made it easier and simple. However, with great UI comes the value of user experience as well. It is necessary to have a sustainable user experience along with a great UI. Hence, this tutorial will help learn a small aspect of optimizing the user experience by showing the loading effect (termed as pre-loaders, placeholders) before the actual data loads.

The preloaders become necessary for the user to experience the data is still loading or being fetched from the server. Until the actual data is fetched from the server and displayed on the screen, the pre-loaders will help users understand what actually is going on. The displaying of preloaders indicates that the actual data has still not loaded due to some reasons such as slow network, app errors, etc. Thus, optimizing the overall user experience. Hence, the pre-loaders are necessary for any mobile applications as well as websites. And here, we are going to learn just that on how to add image pre-loaders before the actual image loads in a Flutter app.

### Create new Flutter project

First, we need to create a new Flutter project. For that, make sure that the [Flutter SDK](https://flutter.dev/docs/get-started/install) and other flutter app development related requirements are properly installed. If everything is properly set up, then in order to create a project, we can simply run the following command in the desired local directory:

```bash
flutter create imagePreloader
```

After the project has been set up, we can navigate inside the project directory and execute the following command in the terminal to run the project in either an available emulator or an actual device:

```bash
flutter run
```

After successfully build, we will get the following result on the emulator screen:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ethv0d5c1v6ka6qb7opb.jpg)

### Creating Home Screen

Since we have our flutter app up and running in the emulator, we can now move to create screens. For that, we need to create a directory called **./screens** inside the **./lib** directory of our project. Inside the **./screens** directory, we need to create a new dart file called **Home.dart**.

In the **Home.dart**, we are going to create a stateful widget to show the image as well as the preloaders. But first, we are going to show a simple App bar by returning a `Scaffold` widget as shown in the code snippet below:

```dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:ui';

class HomePage extends StatefulWidget {
  HomePage({Key key}) : super(key: key);
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<HomePage> {

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            backgroundColor: Colors.white,
            centerTitle: true,
            title: Text(
              "Image",
              style: TextStyle(color: Colors.black87, fontFamily: 'Overpass', fontSize: 20),
            ),
            elevation: 0.0
        ),
        backgroundColor: Colors.white,
        body: Container()
    );
  }
}
```

Here, we have added an App bar using `AppBar` widget in the `Scaffold` widget. The body property returns an empty `Container` widget. 

Now, we need to import the Home.dart file in main.dart and replace the default widget with `HomePage` widget as shown in the code snippet below:

```dart
import 'package:flutter/material.dart';
import 'package:imagePreloader/screens/Home.dart';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: HomePage(),
    );
  }
}
```

Hence, we will get the result as shown in the screenshot below:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ts24uf8dj3t74rkq144o.jpg)

### Adding Image Container to Home Screen

Now, we are going to display an image on the Home screen. For that, we need to fetch a mock image from [pexels](http://pexels.com) or from anywhere. Then, we need to add the URL path of the image to a List called `imagesPath`. 

Note that, we can directly use this URL but we are pushing the URL from `imagesPath` to a new List called `imagesList` because we want to show the Pre-loaders before the image loads on the screen. 

The initializations are provided in the code snippet below:

```dart
List imagesPath = [
    "https://images.pexels.com/photos/2440061/pexels-photo-2440061.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940",
  ];

 List imagesList = new List();
```

Now, we need to create a function to load the image URL from the `imagesPath` list to `imagesList` list. **Remember that we are doing this as an alternative to fetching images from the server. Since we are not using a server to fetch the image, we have to devise the logic to load the image URL manually from the code itself.** 

The implementation of `getImages` function is provided in the code snippet below:

```dart
getImages() {
  imagesList.add(imagesPath[0]);
}
```

Now, we need to call the `getImages` function inside the `initState` method:

```dart
@override
void initState() {
  super.initState();
  getImages();
}
```

 This `initState` method executes before our main build function executes once we enter the Home screen.

Now, we are going to create a image view container in the `Scaffold` widget body. For that, we can use the code from the following code snippet:

```dart
body: SingleChildScrollView(
        child: Padding(
          padding: EdgeInsets.symmetric(horizontal: 5, vertical: 5),
          child: Container(
            margin: EdgeInsets.only(right : 0),
            width: 500,
            height: 350,
            decoration: BoxDecoration(
              color: Colors.black26,
              borderRadius: BorderRadius.circular(16),
            ),
            child: ClipRRect(
              borderRadius: BorderRadius.circular(16),
              child: Image.network(
                  imagesList[0],
                  fit: BoxFit.cover,
              ),
            ),
          )
        )
      ),
    );
```

Here, we have placed the `SingleChildScrollView` widget as a primary parent widget so that the whole body section is scrollable. Then, we have a `Padding` widget to apply some paddings which have `Container` as a child widget. The `Container` widget is configured with some unique properties which provide child widgets as a `ClipRRect` widget. The `ChipRRect` allows us to clip the edges of its child widget. As its child widget, we have used [`Image.network`](http://image.network) widget to display the image.

The result is displayed in the screenshot below:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/d9wjo6ad7ot4r7m4usqm.jpg)

Here, we have got an image on the screen. Now, it is time to add Pre-loaders.

### Adding Shimmering Image Pre-loader

In order to add the image Pre-loader, we are going to make use of the [shimmer](https://pub.dev/packages/shimmer) package. This package provides an easy way to apply the shimmer effect in the Flutter app. It makes the Pre-loader implementation easy as well as optimizes the user experience. 

First, we need to install the shimmer package. For that, we need to add the shimmer package to **pubspec.yaml** file as shown in the code snippet below:

```yaml
dependencies:
  flutter:
    sdk: flutter
    
  shimmer: 1.1.1
```

Now, we need to import the package to the Home.dart as shown in the code snippet below:

```dart
import 'package:shimmer/shimmer.dart';
```

Now, we are going to implement the shimmer preloading effect using the `Shimmer` widget provided by the shimmer package. But first, we need to make some configurations so as to show the shimmers perfectly. So, we need to define some constants as shown in the code snippet below:

```dart
bool _loading = false;
int offset = 0;
int time = 800;
```

Here, the `_loading` Boolean variable is for the conditional rendering of the Image and Pre-loaders. The offset and time value is configured to the `Shimmer` widget to set the time interval till which the pre-loaders need to load. The implementation is provided in the code snippet below:

```dart
body: (_loading)?
        Container(
          color: Colors.white,
          child: SafeArea(
            child: ListView.builder(
              padding: EdgeInsets.all(5),
              itemCount: 2,
              itemBuilder: (BuildContext context, int index) {
                offset += 5;
                time = 800 + offset;
                return Padding(
                  padding: EdgeInsets.symmetric(horizontal: 5, vertical: 5),
                  child: Shimmer.fromColors(
                    highlightColor: Colors.white,
                    baseColor: Colors.grey[500],
                    child: Container(
                      margin: EdgeInsets.only(right : 0),
                      height: 350,
                      width: 270,
                      decoration: BoxDecoration(
                        color: Colors.black26,
                        borderRadius: BorderRadius.circular(16),
                      ),
                    ),
                    period: Duration(milliseconds: time),
                  )
                );
              },
            ),
          )
        ):
         SingleChildScrollView(
          child: Padding(
            padding: EdgeInsets.symmetric(horizontal: 5, vertical: 5),
            child: Container(
              margin: EdgeInsets.only(right : 0),
              width: 500,
              height: 350,
              decoration: BoxDecoration(
                color: Colors.black26,
                borderRadius: BorderRadius.circular(16),
              ),
              child: ClipRRect(
                borderRadius: BorderRadius.circular(16),
                child: Image.network(
                    imagesList[0],
                    fit: BoxFit.cover,
                ),
              ),
            )
          )
        ),
    );
```

Here, we show the Pre-loader template in contrast to the Image template using the `_loading` value as conditional rendering. We have used the `Shimmer` widget inside the `ListView` so as to show multiple loaders which can be controlled by setting the `itemCount` property. We have used the `fromColors` extension provided by the `Shimmer` widget with configured `highlightColor` and `baseColor` properties. We have placed a `Container` widget similar to `Container` in Image template as a child of `Shimmer` in order to display the shimmering effect.

Now, the above template will create a shimmering pre-loader effect. But, we still need to implement the logic to show the pre-loaders. For that, we are going to use the `Timer` function. The `Timer` function will help to delay the loading of the image onto the screen and show the pre-loaders until then. First, we need to import the package that provides the `Timer` function:

```dart
import 'dart:async';
```

Now in `getImages` function, we use the `Timer` to delay the loading of the image and show the shimmer pre-loaders instead. 

In an actual app, we fetch the data from server in which the fetching may take time. Till then, we show some loading effect which improves the overall user experience.

Since we are not pulling data from the server, we need to manually configure the delay. Hence, the implementation is provided in the code snippet below:

```dart
getImages() {
    setState(() {
      _loading = true;
    });
    Timer(Duration(seconds: 5), () => {
      imagesList.add(imagesPath[0]),
      setState(() {
        _loading = false;
      })
    });
  }
```

Now, the final result with shimmering effect Pre-loaders is shown in the demo below:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/gwvjydma8bjgvuzbh368.gif)

We can notice a shimmering loading effect just before the image loads on the screen. Likewise, we can display the shimmer effect from any widget element structure of the screens as the child of the `Shimmer` widget uses the Flutter widgets itself. Hence, it is flexible enough to be shaped into anything.

Finally, we have implemented the image Pre-loader in a Flutter app.

### Conclusion

As we talk about the importance of pre-loaders in optimizing the user experience, we can see the effect it has on the overall app UI and its usage from the demo above. It makes the overall user experience convenient. These types of pre-loaders are used in every app nowadays. So, users expect pre-loaders to happen. It creates a greater impact in terms of visual and understanding of what is going on. Pre-loaders taking a long time can interpret into problems in internet connectivity or some other type of app errors. This makes the user aware of what actually is happening. Hence, it is an important element to have knowledge of for a developer. 

Now, the challenge is to create the preloaders for different widget elements. Here, we implemented the preloaders for the image element which was simple. But, the pre-loaders using the shimmer package can be shaped into anything as it uses the Flutter widgets itself as a child.

For more inspirations for beautifully designed pre-loaders, check out some amazing [Flutter apps](http://instaflutter.com) that have them integrated intuitively.

<hr/>
_[daily.dev](https://api.daily.dev/get?r=devto) delivers the best programming news every new tab. We will rank hundreds of qualified sources for you so that you can hack the future._
[![Daily Poster](https://dev-to-uploads.s3.amazonaws.com/i/b996k4sm4efhietrzups.png)](https://api.daily.dev/get?r=devto)