Flutter开发中记录一个非常好用的图片缓存清理的插件
在flutter开发中,当App项目内存吃紧时,页面中如果图片很多时需要及时清理,如果不能及时清理,会造成内存泄漏,导致App卡顿甚至强制退出或手机死机。
这里我使用extended_image封装了一个全局可用的Widget,亲测IOS和安卓好用。
首先在pubspec.yaml文件中配置插件并下载,执行Pub get。
dependencies:extended_image: ^6.2.0
我使用的是6.2.0版本,基于ExtendedImage我对netWork网络图片组件做了如下封装,内有注释与备注,就不做过多的解释了,完全都能看的懂!
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; // 图片URLfinal 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; // 默认图片路径@overrideState<JudgeNetworkImage> createState() => _JudgeNetworkImageState();
}class _JudgeNetworkImageState extends State<JudgeNetworkImage> {late String _url;@overridevoid initState() {super.initState();_url = widget.url;}@overridevoid dispose() {super.dispose();if (widget.clearMemoryCacheWhenDispose) {// 主动清除图片缓存if (_url.isNotEmpty && _url != (widget.defaultImagePath ?? '')) {final provider = ExtendedNetworkImageProvider(_url);provider.evict();}}}@overrideWidget 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的封装,对性能提升有相当大的帮助!