Flutter中NetworkImage在URL变更时图片不刷新如何解决?
问题原因
- 你的
pageIndex、imgLoading、chapterNumberTracker三个状态变量全部定义在build方法或FutureBuilder的builder回调内,Flutter每次调用setState都会触发组件重绘、执行build逻辑,这三个变量每次都会被重置为初始值,你在点击事件里修改的数值根本不会被持久保存,页面看起来就没有变化。 - 额外问题:你每次切换章节调用setState后,FutureBuilder的future都会重新执行
getAllFilePaths方法请求章节图片列表,属于可优化的重复请求。
解决步骤
- 将三个状态变量移到
_MangaReaderState类中作为类属性,不要放在build方法内,还可以新增缓存字段避免重复请求同一章节的图片列表:
class _MangaReaderState extends State<MangaReader> { final String globalToken; late String chapterId; final ChapterData chapterData; late String mangaId; JsonSearch jsonsearch = JsonSearch(); // 状态变量移到类内部定义 bool imgLoading = false; int chapterNumberTracker = 0; int pageIndex = 0; // 可选:缓存已请求过的章节图片列表 Map<String, List<String>> chapterPagesCache = {}; _MangaReaderState( {required this.globalToken, required this.chapterId, required this.mangaId, required this.chapterData});
- 修改build方法,删除原build、builder方法内三个变量的初始化代码,切换章节时补充重置页码的逻辑:
@override Widget build(BuildContext context) { // 删掉这里的bool imgLoading = false; int chapterNumberTracker = 0; chapterId = chapterData.result[chapterNumberTracker].data.id; return FutureBuilder( // 优先读取缓存,没有再发起请求 future: chapterPagesCache.containsKey(chapterId) ? Future.value(chapterPagesCache[chapterId]) : getAllFilePaths(chapterId, false), builder: (context, AsyncSnapshot<List<String>?> data) { if (data.hasData) { // 删掉这里的int pageIndex = 0; // 请求成功后存入缓存 if(!chapterPagesCache.containsKey(chapterId)){ chapterPagesCache[chapterId] = data.data!; } return Scaffold( appBar: AppBar(), body: SingleChildScrollView( child: Column( children: [ Container( height: 75, width: double.infinity, color: Colors.black54, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Align( alignment: Alignment.center, child: Center( child: Row( children: [ Container( child: IconButton( color: Colors.white, icon: Icon(Icons.skip_previous), onPressed: () { if (chapterNumberTracker != 0) { setState(() { chapterNumberTracker--; pageIndex = 0; // 切换章节后回到第一页 }); } }, ), ), Container( color: Colors.white, child: Text('Chapter ' + (chapterNumberTracker + 1).toString()), ), Container( child: IconButton( icon: Icon( Icons.skip_next, color: Colors.white, ), onPressed: () { setState(() { chapterNumberTracker++; pageIndex = 0; // 切换章节后回到第一页 }); }, ), ) ], ), ), ) ], ), ), Container( color: Colors.black87, child: imgLoading ? CircularProgressIndicator() : InkWell( child: Image( image: NetworkImage(data.data![pageIndex]), ), onDoubleTap: () { setState(() { if (pageIndex != 0) { pageIndex--; } }); }, onTap: () { setState( () { if (data.data!.length != pageIndex + 1) { pageIndex++; } }, ); }, ), ), ], ), ), ); } else { return Center( child: Container( height: 100, width: 100, child: CircularProgressIndicator( color: Colors.white, ), ), ); } }, ); }
- 可选优化:你已经引入了
cached_network_image依赖,可以将原生NetworkImage替换为CachedNetworkImage,自动缓存已加载的图片,提升切换体验:
InkWell( child: CachedNetworkImage( imageUrl: data.data![pageIndex], placeholder: (context, url) => const CircularProgressIndicator(), errorWidget: (context, url, error) => const Icon(Icons.error, color: Colors.white), ), // 原有点击、双击逻辑不变 )
内容的提问来源于stack exchange,提问作者RikSantra
相关产品推荐
相关产品推荐

