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

Flutter:无网络时如何为Image.network的connectionState显示加载状态?

问题:无网络时Image.network显示错误占位图,需替换为加载状态

我在Flutter中通过StreamBuilder<User?>监听authBloc.currentUser流获取用户头像,使用Image.network加载快照中的图片链接。但无网络连接时,Image.network会显示默认错误占位图,我希望这种场景下显示加载状态(而非仅用Text('loading')),该如何解决?

当前代码

Center(
  child: StreamBuilder<User?>(
    stream: authBloc.currentUser,
    builder: (context, snapshot) {
      if (snapshot.hasData) {
        // when data loaded
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Center(
              child: ClipRRect(
                borderRadius: BorderRadius.circular(0.0),
                child: Image.network(
                  snapshot.data!.photoURL!.replaceFirst('s96', 's400')
                ),
              ),
            )
          ]
        );
      } else if (snapshot.hasError || snapshot.error is SocketException) {
        return const Text("Error"); // if has error with internet or any
      }
      return const Text('Loading'); // waiting to load
    },
  ),
)

解决方案

核心问题说明

原来的StreamBuilder错误判断仅处理流本身的异常(比如获取用户信息失败),但图片加载失败(无网络、链接失效等)发生在Image.network的加载阶段,此时StreamBuilder的snapshot已经处于hasData状态,不会触发错误分支。要处理图片加载失败的场景,需要利用Image.network自身的回调参数。

方法一:使用Image.network的loadingBuilder和errorBuilder

直接通过Image.network的内置参数,控制加载中、加载失败时的显示内容:

Center(
  child: StreamBuilder<User?>(
    stream: authBloc.currentUser,
    builder: (context, snapshot) {
      if (snapshot.hasData) {
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Center(
              child: ClipRRect(
                borderRadius: BorderRadius.circular(0.0),
                child: Image.network(
                  snapshot.data!.photoURL!.replaceFirst('s96', 's400'),
                  // 正常加载过程中显示加载状态
                  loadingBuilder: (context, child, loadingProgress) {
                    if (loadingProgress == null) return child;
                    return const CircularProgressIndicator();
                  },
                  // 加载失败时判断是否为网络错误,显示加载状态
                  errorBuilder: (context, error, stackTrace) {
                    // 匹配网络相关异常(SocketException/HttpException等)
                    if (error is SocketException || error is HttpException) {
                      return const CircularProgressIndicator();
                    }
                    // 非网络错误可显示默认头像或其他占位
                    return const Icon(Icons.person, size: 100);
                  },
                ),
              ),
            )
          ]
        );
      } else if (snapshot.hasError) {
        return const Text("获取用户信息失败");
      }
      return const CircularProgressIndicator(); // 流未就绪时的加载状态
    },
  ),
)

关键说明:

  • loadingBuilder:在图片正常加载过程中(从发起请求到资源就绪),返回加载状态组件(比如CircularProgressIndicator)。
  • errorBuilder:捕获图片加载失败的异常,判断是否为网络类错误,若是则返回加载状态;其他错误(如链接无效)可返回默认头像。

方法二:结合全局网络状态监听(可选)

如果需要全局统一处理网络状态,可以使用网络状态监听插件(如connectivity_plus),在网络断开时直接显示加载状态:

  1. 先监听网络状态流,在页面中结合StreamBuilder或状态管理记录当前网络状态。
  2. 在Image.network的errorBuilder或外层判断网络状态,决定显示内容。

这种方法适合需要全局感知网络状态的场景,但会增加依赖,方法一更轻量直接。


内容的提问来源于stack exchange,提问作者It'sPhil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 22:35:23