基于Flutter開發(fā)一個圖片緩存清理插件
在flutter開發(fā)中,當App項目內存吃緊時,頁面中如果圖片很多時需要及時清理,如果不能及時清理,會造成內存泄漏,導致App卡頓甚至強制退出或手機死機。
這里我使用extended_image封裝了一個全局可用的Widget,親測IOS和安卓好用。
首先在pubspec.yaml文件中配置插件并下載,執(zhí)行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; // 圖片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; // 控制圖片加載時的字節(jié)大小限制
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,
// 加載狀態(tài)回調
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;
}
}
/// 處理加載狀態(tài)
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的封裝,對性能提升有相當大的幫助!
到此這篇關于基于Flutter開發(fā)一個圖片緩存清理插件的文章就介紹到這了,更多相關Flutter圖片緩存清理內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
配置android開發(fā)環(huán)境時出現eclipse獲取不到ADT的解決方法
這篇文章主要介紹了配置android開發(fā)環(huán)境時出現eclipse獲取不到ADT的解決方法,涉及針對開發(fā)環(huán)境hosts文件域名映射的修改及eclipse配置的修改技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-12-12
Android 中okhttp自定義Interceptor(緩存攔截器)
這篇文章主要介紹了Android 中okhttp自定義Interceptor(緩存攔截器)的相關資料,需要的朋友可以參考下2017-03-03
Android ViewPager撤消左右滑動切換功能實現代碼
這篇文章主要介紹了Android ViewPager撤消左右滑動切換功能實現代碼,需要的朋友可以參考下2017-04-04
Android NDK開發(fā)的環(huán)境搭建與簡單示例
本文主要介紹Android NDK的知識,這里整理了相關資料,來說明如何搭建相應環(huán)境和簡單實例,幫助大家理解,有興趣的小伙伴可以參考下2016-09-09
Android開發(fā)中RecyclerView組件使用的一些進階技講解
RecyclerView是Android 5.0以來新加入的一個組件,基本上全面優(yōu)于ListView,這里我們將來關注Android開發(fā)中RecyclerView組件使用的一些進階技講解:2016-06-06

