Flutter 封装Image控件,图片加载失败时加载默认图片

通常我们加载网络图片会使用官方自带的Image控件,例如:

Image.network("https://www.gravatar.com/avatar/07e417fe88e9aed744c300d52148bf4a?s=328&d=identicon&r=PG&f=1");

一旦加载的URL地址错误,或者网络加载失败都会抛出异常,而且该方法并没有提供失败或者错误回调,这样我们就没有办法在合适的时机替换上失败的占位图。

经过一番查询后使用一下方式可以获取图片加载成功和失败的回调:

static Image getImage(String url, [double w, double h, Function() onError]) {
    var image = Image.network(url, width: w, height: h);
    var resolve = image.image.resolve(ImageConfiguration.empty);
    resolve.addListener(ImageStreamListener((_, __) {
      print("image success.");
    }, onError: (dynamic exception, StackTrace stackTrace) {
      print("image err.");
      onError();
    }));
    return image;
  }

由于回调就意味着异步,所以操作起来并不是很方便,这才又了封装这一说。

创建ImageWidget.dart文件:

import 'package:flutter/material.dart';

//封装图片加载控件,增加图片加载失败时加载默认图片
class ImageWidget extends StatefulWidget {
  ImageWidget({@required this.url, this.w, this.h, this.defImagePath = "assets/images/ic_launcher_round.png"});

  final String url;
  final double w;
  final double h;
  final String defImagePath;

  @override
  State createState() {
    return _StateImageWidget();
  }
}

class _StateImageWidget extends State {
  Image _image;

  @override
  void initState() {
    super.initState();
    _image = Image.network(
      widget.url,
      width: widget.w,
      height: widget.h,
    );
    var resolve = _image.image.resolve(ImageConfiguration.empty);
    resolve.addListener(ImageStreamListener((_, __) {
      //加载成功
    }, onError: (dynamic exception, StackTrace stackTrace) {
      //加载失败
      setState(() {
        _image = Image.asset(
          widget.defImagePath,
          width: widget.w,
          height: widget.h,
        );
      });
    }));
  }

  @override
  Widget build(BuildContext context) {
    return _image;
  }
}

控件向外暴露图片地址,控件宽高和占位图。其他属性可自行扩展。
在图片加载失败时调用setState重新创建默认占位图,并通知刷新UI。

你可能感兴趣的:(Flutter 封装Image控件,图片加载失败时加载默认图片)