Flutter开发中记录一个非常好用的图片缓存清理的插件

在flutter开发中,当App项目内存吃紧时,页面中如果图片很多时需要及时清理,如果不能及时清理,会造成内存泄漏,导致App卡顿甚至强制退出或手机死机。

这里我使用extended_image封装了一个全局可用的Widget,亲测IOS和安卓好用。

首先在pubspec.yaml文件中配置插件并下载,执行Pub get。

Dart 复制代码
dependencies:
  extended_image: ^6.2.0

我使用的是6.2.0版本,基于ExtendedImage我对netWork网络图片组件做了如下封装,内有注释与备注,就不做过多的解释了,完全都能看的懂!

Dart 复制代码
class JudgeNetworkImage extends StatefulWidget {
  const JudgeNetworkImage(
    this.url, {
    Key? key,
    this.width,
    this.height,
    this.isAvatar = false,
    this.fit = BoxFit.cover,
    this.borderRadius,
    this.shape,
    this.borderWidth = 0.0,
    this.borderColor,
    this.opacity = 1.0,
    this.scale = 1.0,
    this.maxBytes,
    this.filterQuality = FilterQuality.low,
    this.repeat = ImageRepeat.noRepeat,
    this.replaceImgPlayback = false,
    this.enableMemoryCache = true,
    this.clearMemoryCacheIfFailed = true,
    this.clearMemoryCacheWhenDispose = true,
    this.cacheRawData = false,
    this.placeholder,
    this.errorWidget,
    this.loadingWidget,
    this.defaultImagePath,
  }) : super(key: key);

  final String url; // 图片URL
  final double? width; // 宽度
  final double? height; // 高度
  final bool isAvatar; // 是否为头像
  final BoxFit fit; // 适配方式
  final BorderRadius? borderRadius; // 圆角
  final BoxShape? shape; // 形状(圆形/矩形)
  final double borderWidth; // 边框宽度
  final Color? borderColor; // 边框颜色
  final double opacity; // 透明度
  final double scale; // 缩放比例
  final int? maxBytes; // 控制图片加载时的字节大小限制
  final FilterQuality filterQuality; // 缩放质量
  final ImageRepeat repeat; // 重复方式
  final bool replaceImgPlayback; // 更换图片时是否保留旧图
  final bool enableMemoryCache; // 启用内存缓存
  final bool clearMemoryCacheIfFailed; // 加载失败时清除缓存
  final bool clearMemoryCacheWhenDispose; // 组件销毁时清除缓存
  final bool cacheRawData; // 缓存原始数据
  final Widget? placeholder; // 加载中占位图
  final Widget? errorWidget; // 加载失败组件
  final Widget? loadingWidget; // 加载中组件
  final String? defaultImagePath; // 默认图片路径

  @override
  State<JudgeNetworkImage> createState() => _JudgeNetworkImageState();
}

class _JudgeNetworkImageState extends State<JudgeNetworkImage> {
  late String _url;

  @override
  void initState() {
    super.initState();
    _url = widget.url;
  }

  @override
  void dispose() {
    super.dispose();
    if (widget.clearMemoryCacheWhenDispose) {
      // 主动清除图片缓存
      if (_url.isNotEmpty && _url != (widget.defaultImagePath ?? '')) {
        final provider = ExtendedNetworkImageProvider(_url);
        provider.evict();
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    Widget child = Container(
      width: widget.width ?? double.maxFinite,
      height: widget.height ?? double.maxFinite,
      decoration: BoxDecoration(
        // 边框部分
        border: widget.borderWidth > 0
            ? Border.all(
                color: widget.borderColor ?? Colors.transparent,
                width: widget.borderWidth,
              )
            : null,
      ),
      child: ExtendedImage.network(
        _url,
        width: widget.width,
        height: widget.height,
        fit: widget.fit,
        scale: widget.scale,
        filterQuality: widget.filterQuality,
        repeat: widget.repeat,
        gaplessPlayback: widget.replaceImgPlayback,
        enableMemoryCache: widget.enableMemoryCache,
        clearMemoryCacheIfFailed: widget.clearMemoryCacheIfFailed,
        clearMemoryCacheWhenDispose: widget.clearMemoryCacheWhenDispose,
        cacheRawData: widget.cacheRawData,
        maxBytes: widget.maxBytes,
        // 应用透时度
        color: widget.opacity < 1.0
            ? Colors.white.withOpacity(widget.opacity)
            : null,
        colorBlendMode: widget.opacity < 1.0 ? BlendMode.srcIn : null,
        clipBehavior: Clip.none,
        // 加载状态回调
        loadStateChanged: (state) {
          return _handleLoadState(state);
        },
      ),
    );

    if (widget.shape == BoxShape.circle) {
      return ClipOval(
        child: child,
      );
    } else if (widget.borderRadius != null) {
      return ClipRRect(
        borderRadius: widget.borderRadius,
        child: child,
      );
    } else {
      return child;
    }
  }

  /// 处理加载状态
  Widget _handleLoadState(ExtendedImageState state) {
    switch (state.extendedImageLoadState) {
      case LoadState.loading:
        // 加载中显示指示器
        return SizedBox(
          width: widget.width != null ? widget.width! * 0.4 : 42.rpx,
          child: Center(
            child: CircularProgressIndicator(
              valueColor:
                  const AlwaysStoppedAnimation<Color>(AppColors.success),
              strokeWidth: 4.rpx,
            ),
          ),
        );
      case LoadState.completed:
        return state.completedWidget;
      case LoadState.failed:
        // 加载失败 - 显示默认图片并清除缓存
        _clearCacheOnError(state);
        return Container(
          color: const Color(0xFFF2F2F2),
          alignment: Alignment.center,
          child: widget.isAvatar
              ? Image.asset(
                  '${AppGlobal.imgUrl}man_presuppose.png',
                  fit: BoxFit.fill,
                )
              : Image.asset(
                  '${AppGlobal.imgUrl}not_pic.png',
                  width: widget.width != null ? widget.width! * 0.6 : 64.rpx,
                  fit: BoxFit.fitWidth,
                ),
        );
    }
  }

  void _clearCacheOnError(ExtendedImageState state) {
    if (widget.clearMemoryCacheIfFailed && mounted) {
      // 获取图片提供者并清除缓存
      if (state.imageProvider is ExtendedNetworkImageProvider) {
        final provider = state.imageProvider as ExtendedNetworkImageProvider;
        provider.evict();
      }
    }
  }
}

以上就是一个完整的网络图片widget的封装,对性能提升有相当大的帮助!

相关推荐
小雨下雨的雨5 分钟前
Flutter 框架跨平台鸿蒙开发 —— ListView 控件之高效列表渲染艺术
flutter·华为·harmonyos
行者9615 分钟前
Flutter在OpenHarmony平台的文件上传组件深度实践
flutter·harmonyos·鸿蒙
行者9619 分钟前
Flutter跨平台开发适配OpenHarmony:进度条组件的深度实践
开发语言·前端·flutter·harmonyos·鸿蒙
cn_mengbei21 分钟前
Flutter for OpenHarmony 实战:RangeSlider 范围滑块详解
flutter
奋斗的小青年!!22 分钟前
Flutter适配OpenHarmony:打造无缝国际化用户体验的实战指南
flutter·harmonyos·鸿蒙
奋斗的小青年!!23 分钟前
Flutter跨平台数据筛选器:深度适配OpenHarmony实战指南
flutter·harmonyos·鸿蒙
恋猫de小郭33 分钟前
Tailwind 因为 AI 的裁员“闹剧”结束,而 AI 对开源项目的影响才刚刚开始
前端·flutter·ai编程
奋斗的小青年!!2 小时前
Flutter与OpenHarmony深度协同:SnackBar组件的跨平台适配实战
flutter·harmonyos·鸿蒙
行者962 小时前
OpenHarmony Flutter跨平台开发:树形视图组件的实践与性能优化
flutter·性能优化·harmonyos·鸿蒙
LawrenceLan17 小时前
Flutter 零基础入门(九):构造函数、命名构造函数与 this 关键字
开发语言·flutter·dart