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

Flutter中API图片加载失败时,如何显示错误占位图片?

Flutter网络图片加载失败替换为本地占位图解决方案

问题场景:

通过API调用加载图片,当API返回的图片不存在时需要显示错误图片。使用DecorationImage的onError方法时,直接创建AssetImage无法实现图片替换,原代码如下:

Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        image: DecorationImage(
          image: NetworkImage(
            imageUrl,
          ),
          onError: (exception, stackTrace) {
            AssetImage(imgNotFound);
          },
          fit: BoxFit.cover,
        ),
        borderRadius: BorderRadius.circular(7),
      ),
    );
  }

解决方案:

  • DecorationImage的onError回调仅用于错误通知,无法直接修改已设置的image参数。需通过状态管理切换图片源:
    1. 将图片源变量存入组件状态,初始值设为NetworkImage(imageUrl)
    2. 在onError回调中更新状态,将图片源替换为AssetImage(imgNotFound)
    3. 组件重建时会自动使用新的图片源渲染

完整代码示例:

class ImageContainer extends StatefulWidget {
  final String imageUrl;
  final String imgNotFound;

  const ImageContainer({super.key, required this.imageUrl, required this.imgNotFound});

  @override
  State<ImageContainer> createState() => _ImageContainerState();
}

class _ImageContainerState extends State<ImageContainer> {
  late ImageProvider _imageProvider;

  @override
  void initState() {
    super.initState();
    _imageProvider = NetworkImage(widget.imageUrl);
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        image: DecorationImage(
          image: _imageProvider,
          onError: (exception, stackTrace) {
            setState(() {
              _imageProvider = AssetImage(widget.imgNotFound);
            });
          },
          fit: BoxFit.cover,
        ),
        borderRadius: BorderRadius.circular(7),
      ),
    );
  }
}
  • 简化方案:使用Image组件的errorBuilder属性,将其作为Container子组件替代DecorationImage:
Widget build(BuildContext context) {
  return Container(
    width: double.infinity,
    height: double.infinity,
    decoration: BoxDecoration(
      borderRadius: BorderRadius.circular(7),
    ),
    child: ClipRRect(
      borderRadius: BorderRadius.circular(7),
      child: Image.network(
        imageUrl,
        fit: BoxFit.cover,
        errorBuilder: (context, error, stackTrace) {
          return Image.asset(
            imgNotFound,
            fit: BoxFit.cover,
          );
        },
      ),
    ),
  );
}

说明:

  • 第一种方案保留DecorationImage的使用,适合必须用背景图的场景
  • 第二种方案更简洁,利用Image组件自带的错误处理能力,推荐大多数场景使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 03:37:13