Flutter - Default image to Image.network when it fails

60,173

Solution 1

It depends on your use case, but one way to do it is to use FadeInImage which has a property of img for the image that is intended to load, and placeholder, well, for the placeholder

FadeInImage(image: NetworkImage(url), placeholder: AssetImage(assetName)

You can also listen until the image is loaded and show a placeholder yourself until fetching the image resolves.

pseudo code

bool _loaded = false;
var img = Image.network(src);
var placeholder = AssetImage(assetName)

@override
void initState() {
  super.initState();
  img.image.resolve(ImageConfiguration()).addListener((i, b) {
    if (mounted) {
      setState(() => _loaded = true);
    }
  });     
}

@override
Widget build(BuildContext context) { 
  return YourWidget(
    child: _loaded ? img : placeholder,
  );
}

Solution 2

You can do with FadeInImage.assetNetwork

 child: new Container(
      child: FadeInImage.assetNetwork(
          placeholder: 'assets/place_holder.jpg',
          image:url
      )
  )

and in pubspec.yaml

  assets:
  - assets/place_holder.jpg

Solution 3

There is a new package called cached_network_image which does what you need. Here you can set a "loading" image and an "error" image right out of the box.

A flutter library to show images from the internet and keep them in the cache directory. https://pub.dev/packages/cached_network_image#-readme-tab-

CachedNetworkImage(
        imageUrl: "http://via.placeholder.com/350x150",
        placeholder: (context, url) => new CircularProgressIndicator(),
        errorWidget: (context, url, error) => new Icon(Icons.error),
     ),

or you can use your own asset image as a placeholder for example:

...
placeholder: (context, url) => {return Image.asset('assets/img/my_placeholder.png');},

Add this to your package's pubspec.yaml file:

dependencies:
  cached_network_image: ^1.1.1

and import in your dart code:

import 'package:cached_network_image/cached_network_image.dart';

Solution 4

You can use the loadingBuilder, and erroBuilder properties as specified in the widget official documentation:

               Image.network(
                  'https://example.com/image.jpg',
                  errorBuilder: (context, error, stackTrace) {
                    print(error); //do something
                  },
                  loadingBuilder: (BuildContext context, Widget child,
                      ImageChunkEvent loadingProgress) {
                    if (loadingProgress == null) return child;
                    return Center(
                      child: CircularProgressIndicator(
                        value: loadingProgress.expectedTotalBytes != null
                            ? loadingProgress.cumulativeBytesLoaded /
                                loadingProgress.expectedTotalBytes
                            : null,
                      ),
                    );
                  },
                ),

https://api.flutter.dev/flutter/widgets/Image/loadingBuilder.html https://api.flutter.dev/flutter/widgets/ImageErrorWidgetBuilder.html

Solution 5

Problem:

Image.Network is not providing any feature/functionality to show error widget if Image not loaded successfully due to any reason.This means your URL should be correct always?

Flutter team uploaded new video about Image Widget on 13-01-2020 (https://www.youtube.com/watch?v=7oIAs-0G4mw) but still they didn't provide any solution.We hope the flutter team will resolve this issue soon.

Solution: You can use Cached network image which is providing a lot of features/functionalities to load image from URL. To read more about Cached network image please visit:

https://pub.dev/packages/cached_network_image

Sample code of Package:

CachedNetworkImage(   
imageUrl: "http://via.placeholder.com/200x150",  
imageBuilder: 
(context, imageProvider) => 
    Container(
     decoration: BoxDecoration(
      image: DecorationImage(
          image: imageProvider,
          fit: BoxFit.cover,
          colorFilter:
              ColorFilter.mode(Colors.red, BlendMode.colorBurn)),
     ),   
    ),   
 placeholder: (context, url) => 
   CircularProgressIndicator(),  
 errorWidget: (context, url, error) 
  => Icon(Icons.error),
),
Share:
60,173
Jesús Martín
Author by

Jesús Martín

Updated on July 09, 2022

Comments

  • Jesús Martín
    Jesús Martín almost 2 years

    Is there any way you can control exceptions launched by Image.network() so you can provide it a default AssetImage ?

  • Rémi Rousselet
    Rémi Rousselet about 6 years
    You can also listen until the image is loaded talking about ImageProvider would help here. As image contains no listenable.
  • Kornel
    Kornel almost 4 years
    this: placeholder: (context, url) => {return Image.asset('assets/img/my_placeholder.png');}, does not work at all
  • Md. Sulayman
    Md. Sulayman almost 4 years
    how to handle null url with FadeInImAGE??
  • Haley Huynh
    Haley Huynh over 3 years
    you should put full path, not just name.
  • Yumarx Polanco
    Yumarx Polanco over 3 years
    @Kornel try using (context) => Image.asset('assets/img/my_placeholder.png'),
  • Aayush Shah
    Aayush Shah almost 3 years
    placeholder requires absolute path. relative path is not working! Any reasons or suggestions ?