22
            new CircleAvatar(
                              backgroundColor: Colors.black87,
                              backgroundImage: new NetworkImage(url),
                              radius: 45.0,
                            )

I Want to show a local image in CircleAvatar until the NetworkImage fully loads from the internet.

Ajay Kumar
  • 15,250
  • 14
  • 54
  • 53

10 Answers10

22

You may want to try a FadeInImage wrapped in a ClipOval. FadeInImage provides a placeholder property you can use while the network image is loading.

Note: ClipOval can be expensive if you do it a lot, so use it sparingly.

Usman Sabuwala
  • 600
  • 6
  • 14
Collin Jackson
  • 110,240
  • 31
  • 221
  • 152
  • how can I use placeholder for "NetworkImage" until "NetworkImage" is loaded? any example will be highly appreciated. Thanks – Kamlesh May 29 '21 at 06:51
16

There is a new official widget for this now!

First, create a folder called assets in the project root directory.

Then, mention the folder in pubspec.yaml file (also found in the project root directory):

flutter:
  uses-material-design: true
  assets:
    - assets/

You can put a picture there, for example, put this as ./assets/loading.gif.

Loading.gif

(If you changed files in assets folder, hot reload won't work. Make sure you restart the app entirely.)

Now you can refer to the loading file in the code:

FadeInImage.assetNetwork(
  placeholder: 'assets/loading.gif',
  image: 'https://github.com/flutter/website/blob/master/src/_includes/code/layout/lakes/images/lake.jpg?raw=true',
);

For more details: https://flutter.io/docs/cookbook/images/fading-in-images#from-asset-bundle

WSBT
  • 33,033
  • 18
  • 128
  • 133
  • 3
    FadeInImage cannot be passed as the image to the CircleAvatar –  May 12 '19 at 22:37
  • My widget needs 'imageProvider'. Kindly suggest how can I use your FadeInImage and network image solutions to show image? Thanks. – Kamlesh May 29 '21 at 06:41
  • I am using photo_view package available at https://pub.dev/packages/photo_view. My code is as: PhotoView( imageProvider: NetworkImage( widget.photoPath.toString(), ),), Kindly suggest how can I use placeholder image until network image is loaded. Thanks a lot. – Kamlesh May 29 '21 at 06:43
14

Use a StateflWidget and you can add a listener to the ImageStream and override the initState to trigger a replacement between the local image and the one obtained from the internet when it is fully loaded.

I have used a high resolution image to show the loading time:

enter image description here

  var _loadImage = new AssetImage(
      'assets/img/basic2-090_loader_loading-512.png');
  var _myEarth = new NetworkImage(
      "http://qige87.com/data/out/73/wp-image-144183272.png");
  bool _checkLoaded = true;

  @override
  void initState() {
    _myEarth.resolve(new ImageConfiguration()).addListener((_, __) {
      if (mounted) {
        setState(() {
          _checkLoaded = false;
        });
      }
    });
  }


  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: new Center(child: new Container(
          decoration: new BoxDecoration(shape: BoxShape.circle,),
          height: 80.0,
          width: 80.0,
          child: new CircleAvatar(
            backgroundColor: Theme
                .of(context)
                .scaffoldBackgroundColor,
            backgroundImage: _checkLoaded ? _loadImage : _myEarth,
          ),)
        )
    );
  }
}
Shady Aziza
  • 50,824
  • 20
  • 115
  • 113
6

You can also use the frameBuilder property. The good thing: you can implement your custom placeholder widget here.

Image.network('https://example.com/my-image',
  height: 100,
  frameBuilder: (context, child, frame, _) {
    if (frame == null) {
      // fallback to placeholder
      return MyPlaceholderWidget();
    }
    return child;
  }
)
Tien Do Nam
  • 3,630
  • 3
  • 15
  • 30
  • Use of Image.network is good way to make your own widget, as FadeInImage keeps loading the placeholder even when the image is cached and is already there, it still goes through the animations every single time, which is annoying. – Noob Oct 31 '22 at 16:40
5

Two way to solve your problem

1) Using Image.network : If you want to show progressbar,simmer or any other widget when image loading.

  Image.network(
      "URL",
      fit: BoxFit.cover,
      loadingBuilder: (BuildContext ctx, Widget child, ImageChunkEvent loadingProgress) {
        if (loadingProgress == null) {
          return child;
        }else {
          return Center(
            child: CircularProgressIndicator(
              valueColor: AlwaysStoppedAnimation<Color>(Colors.green),
            ),
          );
        }
      },       
  )



2) Using FadeInImage : If you want to display your local image when network image loading

 FadeInImage.assetNetwork( 
    image:"URL",
    placeholder:"assets/loading.png" // your assets image path
    fit: BoxFit.cover,
  )
Sanjayrajsinh
  • 15,014
  • 7
  • 73
  • 78
  • My widget needs 'imageProvider'. Kindly suggest how can I use your solutions? Thanks. – Kamlesh May 29 '21 at 06:39
  • I am using photo_view package available at https://pub.dev/packages/photo_view. My code is as: PhotoView( imageProvider: NetworkImage( widget.photoPath.toString(), ),), Kindly suggest how can I use placeholder image until network image is loaded. Thanks a lot. – Kamlesh May 29 '21 at 06:43
3

While large images load, show a fallback asset!

 new PlutoImage.networkWithPlaceholder("http://68.media.tumblr.com/f7e2e01128ca8eb2b9436aa3eb2a0a33/tumblr_ogwlnpSpcU1sikc68o1_1280.png", new Image.asset("assets/placeholder.png"));

https://github.com/FaisalAbid/pluto

Ajay Kumar
  • 15,250
  • 14
  • 54
  • 53
3

You can Use FadeInImage.

Use a placeholder from asset

FadeInImage.assetNetwork(
                              placeholder: "assets/images/image1.png",
                              image:"URL"
                                ),

Use a placeholder from memory

FadeInImage.memoryNetwork(
                                      placeholder: localImageBytes,
                                      image:"URL"
                                    ),
Abir Ahsan
  • 2,649
  • 29
  • 51
  • I am using photo_view package available at https://pub.dev/packages/photo_view. My code is as: PhotoView( imageProvider: NetworkImage( widget.photoPath.toString(), ),), Kindly suggest how can I use placeholder image until network image is loaded. Thanks a lot. – Kamlesh May 29 '21 at 06:43
  • @Kamlesh Please create a new question – Abir Ahsan May 29 '21 at 11:56
  • 1
    Thanks Abir, I have solved the issue, another stackoverflow user shared the best solution to fix this issue. – Kamlesh May 29 '21 at 15:48
2

I developed a package named flutter_url_image_load_fail to define the loading and failed to load widgets:

LoadImageFromUrl(
    'https://upload.wikimedia.org/wikipedia/commons/1/17/Google-flutter-logo.png', //Image URL to load
    (image) => image, //What widget returns when the image is loaded successfully
    () => Text('Loading...'), //What widget returns when the image is loading
    (IRetryLoadImage retryLoadImage, code , message){ //What widget returns when the image failed to load
        return RaisedButton(
            child: Text('Try Again'),
            onPressed: (){
                retryLoadImage.retryLoadImage(); //Call this method to retry load the image when it failed to load
            },
        );
    },
    requestTimeout: Duration(seconds: 5) //Optionally set the timeout
)
Rodrigo João Bertotti
  • 5,179
  • 2
  • 23
  • 34
0

There is a new cached_network_image package that has a "loading" and an "error" images. Along with auto image caching. https://stackoverflow.com/a/57493334/5502121

You can set as a placeholder anything you want, for example from your assets use Image.asset('assets/images/my_placeholder.png')

Kirill Karmazin
  • 6,256
  • 2
  • 54
  • 42
0

Use foregroundImage with NetworkImage as profile image, and use backgroundImagewithAssetImage` as placeholder image, like this:

const CircleAvatar(
  radius: 60,
  backgroundColor: Colors.white,
  backgroundImage: AssetImage('assets/avatar.png'), // Placeholder
  foregroundImage: NetworkImage('https://xxx.xxx.xx.jpg'), // Profile
),
Michael M.
  • 10,486
  • 9
  • 18
  • 34