Flutter中处理NetworkImage加载失败异常并显示占位图的方法
处理NetworkImage加载失败的CircleAvatar占位图方案
直接使用NetworkImage加载API返回的动态图片时,若链接无效会抛出NetworkImageLoadException导致崩溃,以下是几种可靠的异常处理方案:
方案一:用Image.network的errorBuilder实现快速处理
将CircleAvatar的child替换为Image.network,利用其自带的错误回调返回占位图:
CircleAvatar( radius: radius.r, backgroundColor: Colors.transparent, child: Image.network( imageUrl, fit: BoxFit.cover, width: double.infinity, height: double.infinity, errorBuilder: (context, error, stackTrace) { // 替换为你的占位图资源,比如本地asset或Icon return Image.asset( 'assets/placeholder_avatar.png', fit: BoxFit.cover, ); }, ), );
此方法无需额外依赖,直接利用Flutter原生API完成错误捕获与占位展示。
方案二:借助CachedNetworkImage库(推荐)
使用Flutter生态中常用的图片缓存库cached_network_image,它自带错误处理、加载占位和缓存功能,适合频繁加载动态图片的场景:
CircleAvatar( radius: radius.r, backgroundColor: Colors.transparent, child: CachedNetworkImage( imageUrl: imageUrl, fit: BoxFit.cover, // 加载过程中的占位组件 placeholder: (context, url) => const CircularProgressIndicator(strokeWidth: 2), // 加载失败时的占位组件 errorWidget: (context, url, error) => const Icon(Icons.person, size: 40), ), );
也可以直接将CachedNetworkImageProvider作为backgroundImage使用:
CircleAvatar( backgroundImage: CachedNetworkImageProvider( imageUrl, ), backgroundColor: Colors.transparent, radius: radius.r, // 若需自定义错误占位,仍建议用child方式 );
方案三:自定义ImageProvider(灵活扩展)
如果需要保持CircleAvatar使用backgroundImage的写法,可自定义一个支持 fallback 的ImageProvider,加载失败时自动切换到占位图:
class FallbackImageProvider extends ImageProvider<FallbackImageProvider> { final String primaryUrl; final ImageProvider fallback; FallbackImageProvider(this.primaryUrl, this.fallback); @override ImageStreamCompleter loadImage(FallbackImageProvider key, ImageDecoderCallback decode) { return NetworkImage(primaryUrl) .loadImage(key, decode) .handleError((_) => fallback.loadImage(key, decode)); } @override Future<FallbackImageProvider> obtainKey(ImageConfiguration configuration) { return SynchronousFuture(this); } } // 使用示例 CircleAvatar( backgroundImage: FallbackImageProvider( imageUrl, AssetImage('assets/placeholder_avatar.png'), ), backgroundColor: Colors.transparent, radius: radius.r, );
内容的提问来源于stack exchange,提问作者Belen YB
相关产品推荐
相关产品推荐

