如何使用异步图像更新占位符图像? [英] How do I update a placeholder image with an async image?
问题描述
我正在使用管理器类从缓存中提取图像或发出网络请求.我正在使用一个占位符图像.检索正确的图像后,替换该占位符图像的最佳方法是什么?
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);
}
推荐答案
FutureBuilder
类是针对此类情况设计的.我将修改 _loadImage
以返回图像,而不是设置成员变量.然后,您可以摆脱 initState
并按如下所示修改您的 build()
方法:
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
}
},
);
}
顺便说一句,在不调用 setState
的情况下,切勿突变 State
的成员变量.您的build函数将不会被调用,这是linter最终会抱怨的东西(一旦我们实现它).但是 FutureBuilder
更适合您的用例,因为您不必担心在图像完成加载时状态被处置后会发生什么情况.
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.
这篇关于如何使用异步图像更新占位符图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!