Flutter - Image.network 失败时的默认图像

Posted

技术标签:

【中文标题】Flutter - Image.network 失败时的默认图像【英文标题】:Flutter - Default image to Image.network when it fails 【发布时间】:2018-09-21 03:26:49 【问题描述】:

有什么方法可以控制 Image.network() 启动的异常,以便为它提供默认 AssetImage ?

【问题讨论】:

异常是什么意思? ] 错误,例如试图读取一个不存在的url 【参考方案1】:

这取决于您的用例,但一种方法是使用FadeInImage,它的属性为img,用于要加载的图像,placeholder,好吧,用于占位符

FadeInImage(image: NetworkImage(url), placeholder: AssetImage(assetName)

您还可以在加载图像之前进行监听,并自己显示一个占位符,直到获取图像解决。

伪代码

bool _loaded = false;
var img = Image.network(src);
var placeholder = AssetImage(assetName)

@override
void initState() 
  super.initState();
  img.image.resolve(ImageConfiguration()).addListener((i, b) 
    if (mounted) 
      setState(() => _loaded = true);
    
  );     


@override
Widget build(BuildContext context)  
  return YourWidget(
    child: _loaded ? img : placeholder,
  );

【讨论】:

You can also listen until the image is loaded 谈论ImageProvider 会有所帮助。由于图像不包含可听内容。【参考方案2】:

您可以使用 FadeInImage.assetNetwork

 child: new Container(
      child: FadeInImage.assetNetwork(
          placeholder: 'assets/place_holder.jpg',
          image:url
      )
  )

在 pubspec.yaml 中

  assets:
  - assets/place_holder.jpg

【讨论】:

如何使用 FadeInImAGE 处理 null url?? 您应该输入完整路径,而不仅仅是名称。 占位符需要绝对路径。相对路径不起作用!有什么理由或建议吗?【参考方案3】:

有一个名为cached_network_image 的新软件包可以满足您的需求。 您可以在此处设置开箱即用的“加载”图像和“错误”图像。

一个 Flutter 库,用于显示来自 Internet 的图像并将它们保存在缓存目录中。 https://pub.dev/packages/cached_network_image#-readme-tab-

CachedNetworkImage(
        imageUrl: "http://via.placeholder.com/350x150",
        placeholder: (context, url) => new CircularProgressIndicator(),
        errorWidget: (context, url, error) => new Icon(Icons.error),
     ),

或者您可以使用自己的资产图像作为占位符,例如:

...
placeholder: (context, url) => return Image.asset('assets/img/my_placeholder.png');,

将此添加到您的包的 pubspec.yaml 文件中:

dependencies:
  cached_network_image: ^1.1.1

并导入您的飞镖代码:

import 'package:cached_network_image/cached_network_image.dart';

【讨论】:

this: placeholder: (context, url) => return Image.asset('assets/img/my_placeholder.png');,根本不起作用 @Kornel 尝试使用 (context) => Image.asset('assets/img/my_placeholder.png'),【参考方案4】:

问题:

Image.Network 不提供任何特性/功能来显示错误小部件,如果图像由于任何原因未成功加载。这意味着您的 URL 应该始终正确?

Flutter 团队于 13-01-2020 (https://www.youtube.com/watch?v=7oIAs-0G4mw) 上传了关于 Image Widget 的新视频,但他们仍然没有提供任何解决方案。我们希望 Flutter 团队能尽快解决这个问题。

解决方案: 您可以使用缓存网络图像,它提供了许多特性/功能来从 URL 加载图像。 要了解更多关于缓存网络图像的信息,请访问:

https://pub.dev/packages/cached_network_image

包示例代码:

CachedNetworkImage(   
imageUrl: "http://via.placeholder.com/200x150",  
imageBuilder: 
(context, imageProvider) => 
    Container(
     decoration: BoxDecoration(
      image: DecorationImage(
          image: imageProvider,
          fit: BoxFit.cover,
          colorFilter:
              ColorFilter.mode(Colors.red, BlendMode.colorBurn)),
     ),   
    ),   
 placeholder: (context, url) => 
   CircularProgressIndicator(),  
 errorWidget: (context, url, error) 
  => Icon(Icons.error),
),

【讨论】:

【参考方案5】:

您可以使用小部件官方文档中指定的 loadingBuilder 和 erroBuilder 属性:

               Image.network(
                  'https://example.com/image.jpg',
                  errorBuilder: (context, error, stackTrace) 
                    print(error); //do something
                  ,
                  loadingBuilder: (BuildContext context, Widget child,
                      ImageChunkEvent loadingProgress) 
                    if (loadingProgress == null) return child;
                    return Center(
                      child: CircularProgressIndicator(
                        value: loadingProgress.expectedTotalBytes != null
                            ? loadingProgress.cumulativeBytesLoaded /
                                loadingProgress.expectedTotalBytes
                            : null,
                      ),
                    );
                  ,
                ),

https://api.flutter.dev/flutter/widgets/Image/loadingBuilder.html https://api.flutter.dev/flutter/widgets/ImageErrorWidgetBuilder.html

【讨论】:

【参考方案6】:

我找到了你可以使用它的方法

     SizedBox(
              height: 50,
              width: 50,
              child: FadeInImage(
                  height: 50,
                  width: 50,
            fadeInDuration: const Duration(milliseconds: 500),
                  fadeInCurve: Curves.easeInExpo,
                  fadeOutCurve: Curves.easeOutExpo,
                  placeholder: AssetImage("assets/images/common_screen/ic_default_image.jpg"),
                  image: NetworkImage(imageURL
                  ),
                  imageErrorBuilder: (context, error, stackTrace) 
                      return Container(child: Image.asset("assets/images/common_screen/ic_default_image.jpg"));
                  ,
                  fit: BoxFit.cover),
            )

【讨论】:

以上是关于Flutter - Image.network 失败时的默认图像的主要内容,如果未能解决你的问题,请参考以下文章

Flutter - Image.network 失败时的默认图像

在 Flutter 中使用 network_image_mock 包进行图像测试

当 cached_network_image 或 Image.Network 填充数据时,Flutter 应用程序崩溃很多,仅显示与设备的连接丢失而已

使用 loadingBuilder 时 Flutter Image.network 不显示?

Flutter图片缓存 | Image.network源码分析

无法使用 Flutter Image Network 从 Firebase 存储加载图像