Glide遇到DataBinding的花式用法
作者:互联网
前言
主流的图片加载框架越来越多,对应的配置也很麻烦,加载一张图片需要配置一堆参数才能达到需求,使用 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.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}" />
标签:缓存,val,Glide,fun,context,DataBinding,placeholder,花式 来源: https://blog.csdn.net/mjb00000/article/details/110057200