颤抖如何处理Image.network错误(例如404或错误的URL)

时间:2018-09-29 13:36:02

标签: flutter http-status-code-404

当网址错误或目标地址指向404时,如何处理Image.network

例如尝试

Image.network('https://image.tmdb.org/t/p/w92')

11 个答案:

答案 0 :(得分:9)

我已经通过使用errorBuilder处理了与404相关的网络映像问题。

Image.network('Your image url...',
    errorBuilder: (BuildContext context, Object exception, StackTrace stackTrace) {
        return Text('Your error widget...');
    },
),

errorBuilder property

答案 1 :(得分:4)

当您在加载图像时发现 404 或任何其他错误时,您可以显示来自资产的图像。

我所做的是:

  FadeInImage(
      image: NetworkImage("imageUrl"),
      placeholder: AssetImage(
          "assets/images/placeholder.jpg"),
      imageErrorBuilder:
          (context, error, stackTrace) {
        return Image.asset(
            'assets/images/error.jpg',
            fit: BoxFit.fitWidth);
      },
      fit: BoxFit.fitWidth,
    )

检查 imageErrorBuilder 属性。

答案 2 :(得分:3)

使用Network.image代替NetworkImageWithRetry

https://pub.dartlang.org/documentation/flutter_image/latest/

示例:

var avatar = Image(
  image: new NetworkImageWithRetry('http://example.com/avatars/123.jpg'),
);

答案 3 :(得分:3)

很奇怪,但是使用Image.Provider无法轻松正确地处理错误。 使用此方便的软件包:https://pub.dev/packages/flutter_advanced_networkimage

然后在您的代码中:

backgroundImage: AdvancedNetworkImage(
                    "YOUR IMAGE URL", 
                    fallbackAssetImage: "YOUR DEAULT ASSERT IMAGE eg:assets/default.png"
                  )

答案 4 :(得分:3)

您可以使用ImageStream来处理错误。

class CustomProductImage extends StatelessWidget {
  final String image;

  const CustomProductImage({Key key, this.image}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return buildWidget(image);
  }
}

Widget buildWidget(String url) {

  Image image = Image.network(url, width: 50,height: 50,);

  final ImageStream stream = image.image.resolve(ImageConfiguration.empty);

  stream.addListener(ImageStreamListener((info, call) {
      //you can also handle image loading 
      //example: loading = false;//that's mean image is loaded
  },
      onError: (dynamic exception, StackTrace stackTrace) {
//    print('enter onError start');
//    print(exception);
//    print(stackTrace);
//    print('enter onError end');     
     
   }));

  return image;
}

答案 5 :(得分:1)

我建议使用cached_network_image,它提供了一个添加占位符图像的选项,如果是404或403,还可以添加一个错误小部件。

CachedNetworkImage(
   imageUrl: "https://th.wallhaven.cc/small/q6/q6d1xl.jpg",
   placeholder: new CircularProgressIndicator(),
   errorWidget: new Icon(Icons.error),
),

答案 6 :(得分:0)

我喜欢使用它

String url =
    "https://images.unsplash.com/photo-15856192219-dd823a86ebc5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=3334&q=80";
try {
    return CachedNetworkImage(
        useOldImageOnUrlChange: true,
        imageUrl: url,
        placeholder: (context, url) => CircularProgressIndicator(),
        errorWidget: (context, url, error) {
            return Image(
                image: AssetImage(imageLocation),
            );
        },
    );
} catch (e) {
    return Image(
        image: AssetImage(imageLocation),
    );
}

为了安全起见,使用渔获物

P.S:您可能必须声明CachedNetworkImage的实例

答案 7 :(得分:0)

我遇到了同样的问题,但是我使用FadeInImage类的'imageErrorBuilder'属性解决了这个问题。

以下是有关此链接:https://api.flutter.dev/flutter/widgets/Image/errorBuilder.html

该示例是针对Image.network()创建的,但它也适用于FadeInImage。

这是我的代码:

FadeInImage(
  imageErrorBuilder: (BuildContext context, Object exception, StackTrace stackTrace) {
    print('Error Handler'); 
    return Container(
      width: 100.0,
      height: 100.0,
      child: Image.asset('assets/img/no_disponible.jpg'),
    );
  },
  placeholder: AssetImage('assets/img/loading.gif'), 
  image: NetworkImage(product.getImg()),
  fit: BoxFit.cover,
  height: 100.0,
  width: 100.0,
), 

例如,如果页面的方向不存在,则将执行imageErrorBuilder的功能。

我正在使用Flutter 1.20.1

答案 8 :(得分:0)

我使用了基本的 Image 小部件,并添加了一个错误构建器和一个用于加载状态和实际图像的leadingBuilder 我使用了NetworkImageWithRetry 以便它会尝试多次加载图像并在最后给你一个错误,如果它无法加载图像。

Image(
      image: NetworkImageWithRetry(
      'http://ImageUrl.png',),
      errorBuilder: (context, exception, stackTrack) => Icon(Icons.error,),
      loadingBuilder: (context, exception, stackTrack) => CircularProgressIndicator(),
    )

答案 9 :(得分:0)

我已经为同一个案例实现了这个 StatefulWidget,希望这会有所帮助!!!

    class NetworkImageHandlerViewer extends StatefulWidget {
      final String imageURL;
      bool errorFoundInImageLoad = false;
      NetworkImageHandlerViewer({
        Key key,
        @required this.imageURL,
      }) : super(key: key);

      @override
      _NetworkImageHandlerViewerState createState() =>
          _NetworkImageHandlerViewerState();
    }

    class _NetworkImageHandlerViewerState extends State<NetworkImageHandlerViewer> {
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            Container(
              height: 200,
              // height: MediaQuery.of(context).size.height,
              width: MediaQuery.of(context).size.width,
              // color: Colors.black,
              child: (widget.errorFoundInImageLoad)
                  ? Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Text(
                          "Unable To Fetch Image",
                        ),
                        IconButton(
                          iconSize: 40,
                          onPressed: () {
                            setState(() {
                              if (mounted) {
                                print("reloading image again");
                                setState(() {
                                  widget.errorFoundInImageLoad = false;
                                });
                              }
                            });
                          },
                          icon: Icon(Icons.refresh),
                        ),
                        Text(
                          "Tap Refresh Icon To Reload!!!",
                        ),
                      ],
                    )
                  : Image.network(
                      // widget.question.fileInfo[0].remoteURL,
                      widget.imageURL,
                      //
                      loadingBuilder: (context, child, loadingProgress) =>
                          (loadingProgress == null)
                              ? child
                              : Center(
                                  child: CircularProgressIndicator(),
                                ),
                      errorBuilder: (context, error, stackTrace) {
                        Future.delayed(
                          Duration(milliseconds: 0),
                          () {
                            if (mounted) {
                              setState(() {
                                widget.errorFoundInImageLoad = true;
                              });
                            }
                          },
                        );
                        return SizedBox.shrink();
                      },
                    ),
            ),
            SizedBox(height: 25),
          ],
        );
      }
    }

答案 10 :(得分:0)

https://pub.dev/packages/extended_image

该插件可以轻松处理网络图像加载中的错误

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

class ImageHolder extends StatefulWidget {
  const ImageHolder(
      {Key? key,
      required this.url,
      required this.imageHeight,
      required this.imageWidth})
      : super(key: key);

  final String url;
  final double imageHeight;
  final double imageWidth;

  @override
  _ImageHolderState createState() => _ImageHolderState();
}

class _ImageHolderState extends State<ImageHolder>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  @override
  void initState() {
    _controller = AnimationController(
        vsync: this,
        duration: const Duration(seconds: 3),
        lowerBound: 0.0,
        upperBound: 1.0);
    super.initState();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ExtendedImage.network(
      widget.url,
      fit: BoxFit.contain,
      cache: true,
      loadStateChanged: (ExtendedImageState state) {
        switch (state.extendedImageLoadState) {
          case LoadState.loading:
            _controller.reset();
            return Image.asset(
              'assets/images/loading.gif',
              fit: BoxFit.fill,
            );
          case LoadState.completed:
            _controller.forward();
            return FadeTransition(
              opacity: _controller,
              child: ExtendedRawImage(
                image: state.extendedImageInfo?.image,
                width: widget.imageWidth,
                height: widget.imageHeight,
              ),
            );
          case LoadState.failed:
            _controller.reset();
            state.imageProvider.evict();
            return Image.asset(
              'assets/images/failed.jpg',
            );
        }
      },
    );
  }
}