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

Flutter中使用CachedNetworkImage加载图片出错时如何点击重新加载

CachedNetworkImage 加载失败点击重试实现方案

实现思路

通过状态变量控制CachedNetworkImage的唯一标识,加载失败时返回可点击的自定义错误图标,点击后更新状态变量触发组件重建,重新发起图片加载请求。

基础实现(StatefulWidget 版本)

可以直接封装为通用组件全局复用,代码如下:

import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';

class RetryCachedImage extends StatefulWidget {
  final String imageUrl;
  final BoxFit fit;
  // 可根据需求扩展参数,比如占位组件、错误图标样式等
  const RetryCachedImage({
    super.key,
    required this.imageUrl,
    this.fit = BoxFit.cover,
  });

  @override
  State<RetryCachedImage> createState() => _RetryCachedImageState();
}

class _RetryCachedImageState extends State<RetryCachedImage> {
  int _retryCount = 0;

  @override
  Widget build(BuildContext context) {
    return CachedNetworkImage(
      key: ValueKey(_retryCount), // 重试时更新key触发组件重建
      imageUrl: widget.imageUrl,
      fit: widget.fit,
      // 加载中占位
      placeholder: (context, url) => const Center(
        child: CircularProgressIndicator(strokeWidth: 2, size: 24),
      ),
      // 自定义错误视图
      errorWidget: (context, url, error) {
        return GestureDetector(
          onTap: () {
            // 点击重试更新计数
            setState(() {
              _retryCount += 1;
            });
          },
          // 替换为你需要的指定图标即可
          child: const Icon(
            Icons.refresh,
            size: 36,
            color: Colors.grey,
          ),
        );
      },
    );
  }
}

可选优化

如果需要避免加载到本地缓存的错误资源,可以在重试时先清除对应URL的缓存:

onTap: () {
  // 清除当前URL的图片缓存
  CachedNetworkImage.evictFromCache(widget.imageUrl);
  setState(() {
    _retryCount += 1;
  });
}

轻量实现(无全局重绘版本)

如果不想封装组件、也希望避免触发页面全局重绘,可以用ValueListenableBuilder实现:

// 页面内定义重试计数器
final ValueNotifier<int> _retryCounter = ValueNotifier(0);
final String targetImageUrl = "你的图片地址";

// 组件使用部分
ValueListenableBuilder<int>(
  valueListenable: _retryCounter,
  builder: (context, count, _) {
    return CachedNetworkImage(
      key: ValueKey(count),
      imageUrl: targetImageUrl,
      fit: BoxFit.cover,
      placeholder: (_, __) => const CircularProgressIndicator(),
      errorWidget: (_, __, ___) => GestureDetector(
        onTap: () => _retryCounter.value += 1,
        child: const Icon(Icons.refresh, size: 36, color: Colors.grey),
      ),
    );
  }
)

// 页面销毁时释放资源
@override
void dispose() {
  _retryCounter.dispose();
  super.dispose();
}

内容的提问来源于stack exchange,提问作者Mo_

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 07:06:02