18
            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.

Paresh Mangukiya
  • 14,668
  • 7
  • 90
  • 90
Ajay Kumar
  • 9,400
  • 8
  • 40
  • 48

10 Answers10

19

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.

Collin Jackson
  • 80,972
  • 26
  • 188
  • 132
  • 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
13

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
  • 34,951
  • 15
  • 97
  • 103
12

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

user1032613
  • 17,258
  • 13
  • 73
  • 91
  • 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
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
  • 9,400
  • 8
  • 40
  • 48
3

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
  • 7,872
  • 1
  • 51
  • 57
  • 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

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
  • 760
  • 4
  • 16
  • 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
  • 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
)
WiseTap
  • 3,383
  • 1
  • 16
  • 24
1

To do it you can use a Cached network image package. The CachedNetworkImage can be used directly or through the ImageProvider

Create a CircleAvatar like this

CircleAvatar(
  radius: 50,
  foregroundColor: Colors.transparent,
  backgroundColor: appThemeColor.shade50,
  child: CachedNetworkImage(
    imageUrl: UserInfoData.instance.getUserImageUrl(),
    placeholder: (context, url) => CupertinoActivityIndicator(),
    imageBuilder: (context, image) => CircleAvatar(
      backgroundImage: image,
      radius: 40,
    ),

    errorWidget: (context, url, error) => CircleAvatar(
      backgroundColor: Colors.grey,
      child: userProfileAvatarPlaceholder,
      radius: 40,
    ),
  ),
),

enter image description here

Paresh Mangukiya
  • 14,668
  • 7
  • 90
  • 90
  • 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:44
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
  • 4,127
  • 1
  • 34
  • 30
0

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
  • 468
  • 6
  • 15