前言
主流的圖片加載框架越來越多,對應的配置也很麻煩,加載一張圖片需要配置一堆引數才能達到需求,使用 Glide + DataBinding + Kotlin擴展簡單的幾個類,可以完成方便快速的統一進行配置,
1.定義快取配置項
class DiskCacheOptions private constructor(builder: Builder){
val bitmapPoolSize: Float
val memoryCacheSize: Float
val diskCacheDirPath: String?
val diskCacheFolderName: String
val diskCacheSize: Long
init {
this.bitmapPoolSize = builder.bitmapPoolSize
this.memoryCacheSize = builder.memoryCacheSize
this.diskCacheDirPath = builder.diskCacheDirPath
this.diskCacheFolderName = builder.diskCacheFolderName
this.diskCacheSize = builder.diskCacheSize
}
data class Builder(
var bitmapPoolSize: Float = .0f,
var memoryCacheSize: Float = .0f,
var diskCacheDirPath: String? = null,
var diskCacheFolderName: String = "Image",
var diskCacheSize: Long = 1 * 1024 * 1024
) {
/**
* Bitmap池size, Bitmap池,值范圍 1-3,建議在 Application 中設定
*/
fun setBitmapPoolSize(@FloatRange(from = 1.0, to = 3.0) bitmapPoolSize: Float) = apply { this.bitmapPoolSize = bitmapPoolSize }
/**
* 記憶體快取size, 默認記憶體快取, 值范圍 1-2 建議在 Application 中設定
*/
fun setMemoryCacheSize(@FloatRange(from = 1.0, to = 2.0) memoryCacheSize: Float) = apply { this.memoryCacheSize = memoryCacheSize }
/**
* 磁盤快取檔案夾地址
*/
fun setDiskCacheDirPath(dirPath: String) = apply { this.diskCacheDirPath = dirPath }
/**
* 磁盤快取檔案夾目錄,默認 image
*/
fun setDiskCacheFolderName(folderName: String) =apply { this.diskCacheFolderName = folderName }
/**
* 磁盤快取size,默認 1G
*/
fun setDiskCacheSize(size: Long) = apply { this.diskCacheSize = size }
fun build() = DiskCacheOptions(this)
}
}
2.撰寫一個ImageLoader單例類
ImageLoader類主要用來初始化快取配置項的引數以及Glide的一些其它的函式封裝,
Tip:切勿在代碼里面直接使用Glide.xxx函式,使用ImageLoader類可以方便切換其他圖片加載框架,
class ImageLoader {
companion object {
@Volatile
private var INSTANCES: ImageLoader? = null
fun getDefault(): ImageLoader = INSTANCES ?: synchronized(this){ ImageLoader().also { INSTANCES = it }}
}
fun diskCacheOptions() = DiskCacheOptions.Builder()
/**
* 暫停當前背景關系中的Glide請求
*/
fun pauseRequests(context: Context) {
Glide.with(context).pauseRequests()
}
/**
* 暫停所有Glide請求
*/
fun pauseAllRequests(context: Context) {
Glide.with(context).pauseAllRequests()
}
/**
* 恢復Glide請求
*/
fun resumeRequests(context: Context) {
Handler(Looper.getMainLooper()).post { Glide.with(context).resumeRequests() }
}
/**
* 清除Glide的磁盤快取
*/
fun clearDiskCache(context: Context) {
Glide.get(context).clearDiskCache()
}
/**
* 清除Glide的磁盤快取,與上面函式作用一致,獲取背景關系的方式不同而已,
*/
fun clear(view: View) {
Glide.with(view).clear(view)
}
/**
* 清除Glide的記憶體快取
*/
fun clearMemory(context: Context) {
Glide.get(context).clearMemory()
}
/**
* 清除一些記憶體快取,具體數量取決于給應用分配的級別,
*/
fun trimMemory(context: Context, level: Int) {
Glide.get(context).trimMemory(level)
}
/**
* 獲取磁盤快取的資料大小,單位:KB
*/
fun getDiskCacheSize(context: Context): Long {
val options = diskCacheOptions().build()
val diskCacheDirPath = options.diskCacheDirPath ?: context.filesDir.path
val diskCacheFolderName = options.diskCacheFolderName
val file = File("$diskCacheDirPath${File.separator}$diskCacheFolderName")
var blockSize = 0L
try {
blockSize = if (file.isDirectory) getFileSizes(file) else getFileSize(file)
} catch (e: Exception) {
e.printStackTrace()
}
return blockSize
}
private fun getFileSizes(file: File): Long {
var size = 0L
file.listFiles()?.forEach {
if (it.isDirectory) {
size += getFileSizes(it)
} else {
try {
size += getFileSize(it)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
return size
}
private fun getFileSize(file: File): Long {
var size = 0L
if (file.exists()) {
FileInputStream(file).use {
size = it.available().toLong()
}
}
return size
}
}
3.集成AppGlideModule類,配置記憶體與磁盤快取設定
@GlideModule
class DiskCacheModule: AppGlideModule() {
override fun applyOptions(context: Context, builder: GlideBuilder) {
// 設定記憶體快取
val mOptions = ImageLoader.getDefault().diskCacheOptions().build()
// 記憶體快取大小計算器
val mCalculator = MemorySizeCalculator.Builder(context)
.setBitmapPoolScreens(mOptions.bitmapPoolSize)
.setMemoryCacheScreens(mOptions.memoryCacheSize)
.build()
// Bitmap池, LruBitmapPool:負責控制快取
builder.setBitmapPool(LruBitmapPool(mCalculator.bitmapPoolSize.toLong()))
// 記憶體快取
builder.setMemoryCache(LruResourceCache(mCalculator.memoryCacheSize.toLong()))
// 設定磁盤快取
val mDiskCacheDirPath = mOptions.diskCacheDirPath ?: context.filesDir.path
builder.setDiskCache(DiskLruCacheFactory(mDiskCacheDirPath, mOptions.diskCacheFolderName, mOptions.diskCacheSize))
// 日志
builder.setLogLevel(Log.ERROR)
}
override fun isManifestParsingEnabled(): Boolean = false
}
4.撰寫Glide的擴展,添加DataBinding注解,方便在xml中呼叫,
@BindingAdapter(
value = ["imageUrl", "placeholder", "error", "fallback", "loadWidth", "loadHeight", "cacheEnable"],
requireAll = false
)
fun setImageUrl(
view: ImageView,
source: Any? = null,
placeholder: Drawable? = null,
error: Drawable? = null,
fallback: Drawable? = null,
width: Int? = -1,
height: Int? = -1,
cacheEnable: Boolean? = true
) {
// 計算位圖尺寸,如果位圖尺寸固定,加載固定大小尺寸的圖片,如果位圖未設定尺寸,那就加載原圖,Glide加載原圖時,override引數設定 -1 即可,
val widthSize = (if ((width ?: 0) > 0) width else view.width) ?: -1
val heightSize = (if ((height ?: 0) > 0) height else view.height) ?: -1
// 根據定義的 cacheEnable 引數來決定是否快取
val diskCacheStrategy = if (cacheEnable == true) DiskCacheStrategy.AUTOMATIC else DiskCacheStrategy.NONE
// 設定編碼格式,在Android 11(R)上面使用高清無損壓縮格式 WEBP_LOSSLESS , Android 11 以下使用PNG格式,PNG格式時會忽略設定的 quality 引數,
val encodeFormat = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) Bitmap.CompressFormat.WEBP_LOSSLESS else Bitmap.CompressFormat.PNG
Glide.with(view.context)
.asDrawable()
.load(source)
.placeholder(placeholder)
.error(error)
.fallback(fallback)
.thumbnail(0.33f)
.override(widthSize, heightSize)
.skipMemoryCache(false)
.sizeMultiplier(0.5f)
.format(DecodeFormat.PREFER_ARGB_8888)
.encodeFormat(encodeFormat)
.encodeQuality(80)
.diskCacheStrategy(diskCacheStrategy)
.transition(DrawableTransitionOptions.withCrossFade())
.into(view)
}
5.初始化ImageLoader
class AppContext : Application() {
override fun onCreate() {
super.onCreate()
ImageLoader.getDefault().diskCacheOptions()
.setDiskCacheDirPath(getExternalFilesDir("Cache")?.path ?: filesDir.path)
.setDiskCacheFolderName("Image")
.setDiskCacheSize(2 * 1024 * 1024) // 設定磁盤快取2G
.setBitmapPoolSize(2.0f)
.setMemoryCacheSize(1.5f)
.build()
}
}
6.xml中的用法
app:imageUrl="@{data.contentUri}"
app:error="@{@drawable/draw_media_placeholder}"
app:fallback="@{@drawable/draw_media_placeholder}"
app:placeholder="@{@drawable/draw_media_placeholder}"
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/media_thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{(view) -> data.onClick(view, data)}"
app:cacheEnable="@{false}"
app:imageUrl="@{data.source.contentUri}"
app:error="@{@drawable/draw_media_placeholder}"
app:fallback="@{@drawable/draw_media_placeholder}"
app:placeholder="@{@drawable/draw_media_placeholder}" />
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/227562.html
標籤:其他
