【发布时间】:2021-10-22 18:26:52
【问题描述】:
我有一个关于在有状态小部件中使用 Image.network 更新图像的问题,当更改 set State 中的 url 时它不会更新,但是当我进行热重载时,图像更新了。
有人知道为什么会这样吗?
【问题讨论】:
-
您能否添加一些代码来演示您的尝试?您尝试过哪些 Flutter 版本?
-
对不起,我认为我在这个问题上犯了错误。谢谢
我有一个关于在有状态小部件中使用 Image.network 更新图像的问题,当更改 set State 中的 url 时它不会更新,但是当我进行热重载时,图像更新了。
有人知道为什么会这样吗?
【问题讨论】:
如果 URL 和之前一样,尝试在 url 中添加一些随机查询字符串,例如:
Image.network(url + "?v=1");
【讨论】:
为 Image.network 提供一个以 url 作为值的键。
key: ValueKey(url)
【讨论】:
这将确保当小部件树被重建时,图像小部件得到 也重建了
Image(
image: NetworkImageSSL(_imageUrlPath),
fit: BoxFit.cover,
key: ValueKey(new Random().nextInt(100)),),
),
然后清除图片缓存
In my case have to clear image cache when image is uploaded to server
Ex=>
saveDataToServer(){
if(onSucess){
imageCache.clear();
imageCache.clearLiveImages();
}
}
【讨论】:
清除两个图像缓存并添加一个密钥是可行的,但这似乎有点矫枉过正。 Ian 的回答是在 url 中使用一个参数,但我想要一点缓存,不想用参数请求服务器。 所以我最终得到了以下解决方案,它使用了 intl 包中的 DateFormat。
// Make parameter using DateFormat. This image will be cached for a minute.
var nowParam = DateFormat('yyyyddMMHHmm').format(DateTime.now());
// Use # instead of ? or & in url as nothing after # is transmitted to the server.
var img = Image.network(url + '#' + nowParam);
【讨论】:
如果我们在您调用 setState(() {}) 方法时将一些随机数附加到 url 或一些随机键到小部件,则将从服务器请求图像,这是不好的,所以维护 url 的版本号并在您想要更新图像时更新版本号。
class ImageRefreshDemo extends StatefulWidget {
ImageRefreshDemo({
Key? key,
}) : super(key: key);
@override
_ImageRefreshDemoState createState() => _ImageRefreshDemoState();
}
class _ImageRefreshDemoState extends State<ImageRefreshDemo> {
final String _imageUrl = 'image url';
int _imageVersion = 1;
Future<void> _refreshImage() async {
//call API & update the image
_imageVersion++;
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Image Refresh Demo'),
),
body: Image.network(
'$_imageUrl?v=$_imageVersion',
),
floatingActionButton: FloatingActionButton(
child: Icon(
Icons.edit,
color: Colors.white,
),
onPressed: _refreshImage,
),
);
}
}
【讨论】:
我通过向 Image.newtwork 添加一个密钥值解决了这个问题,然后你需要在它重新加载之前删除缓存。
imageCache.clear();
Image myimage = Image.network('url', key: ValueKey(new Random().nextInt(100)),);
【讨论】: