Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I update a placeholder image with an async image?

Tags:

flutter

dart

I'm using a manager class to either pull images from a cache or make a network request. I'm using a placeholder image. What's the best way to replace that placeholder image when the proper image is retrieved?

final ItemManager _manager;
final Item _item;
var _itemImage =
  new Image.asset('assets/images/icons/ic_placeholder.png');

@override
Widget build(BuildContext context) {
  _loadImage();
  return new Container(
    child: _itemImage,
  );
}

_loadImage() async {
  var file = await _manager.itemImageForImageUrl(_item.imageUrl);
  _stickerImage = new Image.file(file);
}
like image 585
Albert Lardizabal Avatar asked May 31 '17 16:05

Albert Lardizabal


People also ask

What is SwiftUI AsyncImage?

This is the exact approach used in almost all the apps where the images are asynchronously loaded and cached (in the best case scenerio). You can implement asynchronous image loading in SwiftUI for iOS 15+ using AsyncImage .

How do you lazy load images on flutter?

First, you need to add cached_network_image Flutter package in your project by adding following lines in pubspec. yaml file. Cached_network_image both caching and lazy loading while scrolling on your app. The images under the view will not get loaded untill it comes to screen view on scroll.


2 Answers

The FutureBuilder class is designed for cases like this. I would modify _loadImage to return the image instead of setting a member variable. Then you can get rid of initState and modify your build() method as follows:

@override
Widget build(BuildContext context) {
  return new FutureBuilder(
    future: _loadImage(),
    builder: (BuildContext context, AsyncSnapshot<Image> image) {
      if (image.hasData) {
        return image.data;  // image is ready
      } else {
        return new Container();  // placeholder
      }
    },
  );
}

As an aside, you should never mutate member variables of your State without calling setState. Your build function won't be called and this is something that the linter will eventually complain about (as soon as we implement it). But FutureBuilder is a much better fit for your use case because you won't have to worry about what happens if your State is disposed by the time the image finishes loading.

like image 164
Collin Jackson Avatar answered Sep 28 '22 08:09

Collin Jackson


I'd recommend using flutter_image "to load images from the network with a retry mechanism."

You can pair it with a placeholder like this:

new FadeInImage(
  placeholder: _itemImage,
  image: new NetworkImageWithRetry('https://example.com/img.jpg'),
),
like image 28
Westy92 Avatar answered Sep 28 '22 08:09

Westy92