You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中NetworkImage在URL变更时图片不刷新如何解决?

问题原因
  • 你的pageIndex、imgLoading、chapterNumberTracker三个状态变量全部定义在build方法或FutureBuilder的builder回调内,Flutter每次调用setState都会触发组件重绘、执行build逻辑,这三个变量每次都会被重置为初始值,你在点击事件里修改的数值根本不会被持久保存,页面看起来就没有变化。
  • 额外问题:你每次切换章节调用setState后,FutureBuilder的future都会重新执行getAllFilePaths方法请求章节图片列表,属于可优化的重复请求。
解决步骤
  1. 将三个状态变量移到_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});
  1. 修改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,
            ),
          ),
        );
      }
    },
  );
}
  1. 可选优化:你已经引入了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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 21:54:05