How to show progress indicator while loading Image.network() in Flutter

aakashp

Aakashp

Posted on January 23, 2022

How to show progress indicator while loading Image.network() in Flutter

cover image
Hello readers, Recently Flutter is in trend and many users may be developing apps in flutter. And one of the basic widget in flutter is Image which is used almost in all app. So let's first see what is this Image Widget.

Image as you can guess by the name is used to show the image. Now this widget has 4 named constructors Image.assets(), Image.file(), Image.network(), Image.memory().

If you are a Flutter developer then you may already know what all these types do and what their use is. We will discuss Image. network().

Image.network() is used to show an image from the internet. You give this widget a URL and it will do all the magic of downloading and showing an image on the screen. Below is the constructor of the Image.network(). As you can see the first argument is src which is the URL of the image file. Other than that there are many other arguments but we will only focus on two frameBuilder, loadingBuilder.

Image Image.network(
  String src, {
  Key? key,
  double scale = 1.0,
  Widget Function(BuildContext, Widget, int?, bool)? frameBuilder,
  Widget Function(BuildContext, Widget, ImageChunkEvent?)? loadingBuilder,
  Widget Function(BuildContext, Object, StackTrace?)? errorBuilder,
  String? semanticLabel,
  bool excludeFromSemantics = false,
  double? width,
  double? height,
  Color? color,
  Animation<double>? opacity,
  BlendMode? colorBlendMode,
  BoxFit? fit,
  AlignmentGeometry alignment = Alignment.center,
  ImageRepeat repeat = ImageRepeat.noRepeat,
  Rect? centerSlice,
  bool matchTextDirection = false,
  bool gaplessPlayback = false,
  FilterQuality filterQuality = FilterQuality.low,
  bool isAntiAlias = false,
  Map<String, String>? headers,
  int? cacheWidth,
  int? cacheHeight,
})
Enter fullscreen mode Exit fullscreen mode

Frame Builder and Loading Builder are the two optional function arguments. Let's see each of them and why are they used.

loadingBuilder: It is called while the image is being downloaded. Below is the description of loadingBuilder from the flutter docs.

A builder that specifies the widget to display to the user while an image is still loading.
If this is null, and the image is loaded incrementally (e.g. over a network), the user will receive no indication of the progress as the bytes of the image are loaded.
For more information on how to interpret the arguments that are passed to this builder, see the documentation on [ImageLoadingBuilder].

frameBuilder: Below is the description of frameBuilder from the Flutter docs.

A builder function responsible for creating the widget that represents this image.
If this is null, this widget will display an image that is painted as soon as the first image frame is available (and will appear to "pop" in if it becomes available asynchronously). Callers might use this builder to add effects to the image (such as fading the image in when it becomes available) or to display a placeholder widget while the image is loading.
To have finer-grained control over the way that an image's loading progress is communicated to the user, see [loadingBuilder].

In short, this function is called when the first frame of the image is built. This function deals with how to build the frames of an image.

Ok, now lots of theory let us see this in practice.
First, let's see how we use Image.network() usually.

Image.network(
        "https://images.unsplash.com/photo-1526666923127- b2970f64b422?q=1080&h=720")
Enter fullscreen mode Exit fullscreen mode

We just give the URL of the image in its constructor. But the output of this may look like this. Suddenly the image appears when it got downloaded.

Now we will use loadingBuilder and frameBuilder to show circular progress indicator while the image is loading.

Center(
child: Image.network(
"https://images.unsplash.com/photo-1526666923127-b2970f64b422",
frameBuilder: (context, child, frame, wasSynchronouslyLoaded) {
return child;
},
loadingBuilder: (context, child, loadingProgress) {
if (loadingProgress == null) {
return child;
} else {
return Center(
child: CircularProgressIndicator(),
);
}
Enter fullscreen mode Exit fullscreen mode

While the image is being downloaded it will show the widget from the loading builder and when the download is completed it will show the widget from the frame builder.

In the loading builder, we are first checking if the progress is null or not. If it is null we directly return the child else we show the circular progress indicator. We can also show progress value by using the data from loadingProgress.

And after that frame builder will return the child which contains the actual image. You can also wrap the child inside some animation to make it look good.

You can also show loading by using a placeholder gif image or using the stack as shown here.
NOTE: There may be another method to achieve the same thing effectively, if you find anything wrong or better than this please let me know.

💖 💪 🙅 🚩
aakashp
Aakashp

Posted on January 23, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related