如何使用异步图像更新占位符图像?
How do I update a placeholder image with an async image?
我正在使用管理器 class 从缓存中提取图像或发出网络请求。我正在使用占位符图像。当检索到正确的图像时,替换该占位符图像的最佳方法是什么?
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
class 就是为这种情况设计的。我会将图像 _loadImage
修改为 return 而不是设置成员变量。然后你可以摆脱 initState
并修改你的 build()
方法如下:
@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
的成员变量。您的构建函数不会被调用,这是 linter 最终会抱怨的事情(一旦我们实现它)。但是 FutureBuilder
更适合您的用例,因为您不必担心如果您的状态在图像完成加载时被处置会发生什么。
我建议使用 flutter_image "to load images from the network with a retry mechanism."
您可以将它与这样的占位符配对:
new FadeInImage(
placeholder: _itemImage,
image: new NetworkImageWithRetry('https://example.com/img.jpg'),
),
我正在使用管理器 class 从缓存中提取图像或发出网络请求。我正在使用占位符图像。当检索到正确的图像时,替换该占位符图像的最佳方法是什么?
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
class 就是为这种情况设计的。我会将图像 _loadImage
修改为 return 而不是设置成员变量。然后你可以摆脱 initState
并修改你的 build()
方法如下:
@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
的成员变量。您的构建函数不会被调用,这是 linter 最终会抱怨的事情(一旦我们实现它)。但是 FutureBuilder
更适合您的用例,因为您不必担心如果您的状态在图像完成加载时被处置会发生什么。
我建议使用 flutter_image "to load images from the network with a retry mechanism."
您可以将它与这样的占位符配对:
new FadeInImage(
placeholder: _itemImage,
image: new NetworkImageWithRetry('https://example.com/img.jpg'),
),