失败时重新加载缓存的网络图像
Reload cached Network Image upon failure
对于在列表视图中显示的图像,我有 class。有时图像失败并且 setstate 不会重新加载图像,也没有任何我想到的方法有效,即使在分配唯一键值时也是如此。
图片classreturns这段代码:
CachedNetworkImage(
imageUrl: widget.url,
fit: BoxFit.fitWidth,
progressIndicatorBuilder: (context, url, downloadProgress) =>
Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height * 0.5,
width: MediaQuery.of(context).size.width,
child: CircularProgressIndicator(
value: downloadProgress.progress),
),
errorWidget: (){
return Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height * 0.5,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
Icons.perm_scan_wifi,
color: Colors.grey[600],
size: 50,
),
Padding(
padding: const EdgeInsets.only(bottom: 20, top: 25),
child: Text(
'Failed To Load Image',
style: TextStyle(color: Colors.white, fontSize: 17),
),
),
Padding(
padding: const EdgeInsets.only(
bottom: 12.0, left: 10, right: 10),
child: Text(
'Check your internet connection and try again.',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.grey),
),
),
FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
child: Text('Retry',
style: TextStyle(color: Colors.black)),
onPressed: () {
setState(() {});
},
color: Pigment.fromString('#FFCC00'),
)
],
),
);
},
)
能否请您提出一种在失败时重新加载图像的方法,我只能使用缓存的网络图像,没有其他包有用,因为我是唯一的缓存关键功能。
您可以复制粘贴运行下面的完整代码
您可以使用 ValueNotifier
更改 cacheKey
of CachedNetworkImage
在工作演示中
第 1 步:图像未加载 airplane mode
第 2 步:关闭 airplane mode
第 3 步:然后单击 Retry button
,然后单击 _networklHasErrorNotifier.value++
第 4 步:ValueListenableBuilder
用新的 cacheKey
重建 CachedNetworkImage
代码片段
ValueNotifier<int> _networklHasErrorNotifier = ValueNotifier(0);
...
ValueListenableBuilder(
valueListenable: _networklHasErrorNotifier,
builder: (BuildContext context, int count, Widget child) {
print("rebuild");
return CachedNetworkImage(
cacheKey: _networklHasErrorNotifier.value.toString(),
...
onPressed: () {
print("clicked");
_networklHasErrorNotifier.value++;
},
工作演示
完整代码
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ValueNotifier<int> _networklHasErrorNotifier = ValueNotifier(0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ValueListenableBuilder(
valueListenable: _networklHasErrorNotifier,
builder: (BuildContext context, int count, Widget child) {
print("rebuild");
return CachedNetworkImage(
cacheKey: _networklHasErrorNotifier.value.toString(),
imageUrl: "https://via.placeholder.com/350x150",
fit: BoxFit.fitWidth,
progressIndicatorBuilder:
(context, url, downloadProgress) => Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height * 0.5,
width: MediaQuery.of(context).size.width,
child: CircularProgressIndicator(
value: downloadProgress.progress),
),
errorWidget: (context, url, error) {
return Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height * 0.5,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
Icons.perm_scan_wifi,
color: Colors.grey[600],
size: 50,
),
Padding(
padding:
const EdgeInsets.only(bottom: 20, top: 25),
child: Text(
'Failed To Load Image',
style: TextStyle(
color: Colors.white, fontSize: 17),
),
),
Padding(
padding: const EdgeInsets.only(
bottom: 12.0, left: 10, right: 10),
child: Text(
'Check your internet connection and try again.',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.grey),
),
),
FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
child: Text('Retry',
style: TextStyle(color: Colors.black)),
onPressed: () {
print("clicked");
_networklHasErrorNotifier.value++;
//setState(() {});
},
//color: Pigment.fromString('#FFCC00'),
)
],
),
);
},
);
})
],
),
),
);
}
}
我也是,当我的列表视图在列表项图像中一次又一次地重新加载时向上或向下滚动时遇到相同类型的问题。
最后,我在 ListViewBuilder 中添加 cacheExtent (int value) 参数,这个问题就解决了,
ListView.builder(
cacheExtent: 9999,
itemCount: snapshot.data.items.length,
itemBuilder: (context, I)
{
return getItemCard(
child: CachedNetworkImage(
imageUrl: snapshot.data.items[i],
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
);
});
对于在列表视图中显示的图像,我有 class。有时图像失败并且 setstate 不会重新加载图像,也没有任何我想到的方法有效,即使在分配唯一键值时也是如此。
图片classreturns这段代码:
CachedNetworkImage(
imageUrl: widget.url,
fit: BoxFit.fitWidth,
progressIndicatorBuilder: (context, url, downloadProgress) =>
Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height * 0.5,
width: MediaQuery.of(context).size.width,
child: CircularProgressIndicator(
value: downloadProgress.progress),
),
errorWidget: (){
return Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height * 0.5,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
Icons.perm_scan_wifi,
color: Colors.grey[600],
size: 50,
),
Padding(
padding: const EdgeInsets.only(bottom: 20, top: 25),
child: Text(
'Failed To Load Image',
style: TextStyle(color: Colors.white, fontSize: 17),
),
),
Padding(
padding: const EdgeInsets.only(
bottom: 12.0, left: 10, right: 10),
child: Text(
'Check your internet connection and try again.',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.grey),
),
),
FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
child: Text('Retry',
style: TextStyle(color: Colors.black)),
onPressed: () {
setState(() {});
},
color: Pigment.fromString('#FFCC00'),
)
],
),
);
},
)
能否请您提出一种在失败时重新加载图像的方法,我只能使用缓存的网络图像,没有其他包有用,因为我是唯一的缓存关键功能。
您可以复制粘贴运行下面的完整代码
您可以使用 ValueNotifier
更改 cacheKey
of CachedNetworkImage
在工作演示中
第 1 步:图像未加载 airplane mode
第 2 步:关闭 airplane mode
第 3 步:然后单击 Retry button
,然后单击 _networklHasErrorNotifier.value++
第 4 步:ValueListenableBuilder
用新的 cacheKey
CachedNetworkImage
代码片段
ValueNotifier<int> _networklHasErrorNotifier = ValueNotifier(0);
...
ValueListenableBuilder(
valueListenable: _networklHasErrorNotifier,
builder: (BuildContext context, int count, Widget child) {
print("rebuild");
return CachedNetworkImage(
cacheKey: _networklHasErrorNotifier.value.toString(),
...
onPressed: () {
print("clicked");
_networklHasErrorNotifier.value++;
},
工作演示
完整代码
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ValueNotifier<int> _networklHasErrorNotifier = ValueNotifier(0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ValueListenableBuilder(
valueListenable: _networklHasErrorNotifier,
builder: (BuildContext context, int count, Widget child) {
print("rebuild");
return CachedNetworkImage(
cacheKey: _networklHasErrorNotifier.value.toString(),
imageUrl: "https://via.placeholder.com/350x150",
fit: BoxFit.fitWidth,
progressIndicatorBuilder:
(context, url, downloadProgress) => Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height * 0.5,
width: MediaQuery.of(context).size.width,
child: CircularProgressIndicator(
value: downloadProgress.progress),
),
errorWidget: (context, url, error) {
return Container(
alignment: Alignment.center,
height: MediaQuery.of(context).size.height * 0.5,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(
Icons.perm_scan_wifi,
color: Colors.grey[600],
size: 50,
),
Padding(
padding:
const EdgeInsets.only(bottom: 20, top: 25),
child: Text(
'Failed To Load Image',
style: TextStyle(
color: Colors.white, fontSize: 17),
),
),
Padding(
padding: const EdgeInsets.only(
bottom: 12.0, left: 10, right: 10),
child: Text(
'Check your internet connection and try again.',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.grey),
),
),
FlatButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
child: Text('Retry',
style: TextStyle(color: Colors.black)),
onPressed: () {
print("clicked");
_networklHasErrorNotifier.value++;
//setState(() {});
},
//color: Pigment.fromString('#FFCC00'),
)
],
),
);
},
);
})
],
),
),
);
}
}
我也是,当我的列表视图在列表项图像中一次又一次地重新加载时向上或向下滚动时遇到相同类型的问题。
最后,我在 ListViewBuilder 中添加 cacheExtent (int value) 参数,这个问题就解决了,
ListView.builder(
cacheExtent: 9999,
itemCount: snapshot.data.items.length,
itemBuilder: (context, I)
{
return getItemCard(
child: CachedNetworkImage(
imageUrl: snapshot.data.items[i],
placeholder: (context, url) => CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
),
);
});