Android 优雅封装Glide

文章目录

  • Android 优雅封装Glide
    • 核心思想
    • 定义策略接口
    • 定义图片选项
    • 实现Glide策略
    • 图片管理类
    • 使用

Android 优雅封装Glide

核心思想

使用策略模式实现不同图片加载框架的切换,使用建造者设计模式处理不同参数,最后通过 ImageLoader 进行管理。

定义策略接口

interface ILoaderStrategy {

    fun loadImage(configs: ImageOptions)

    fun clearDiskCache(context: Context)

    fun clearMemoryCache(context: Context)

    fun clearAll(context: Context) {
        clearDiskCache(context)
        clearMemoryCache(context)
    }

    fun clear(imageView: ImageView)
}

定义图片选项

class ImageOptions private constructor() {
    var targetObj: Any? = null // 生命周期对象
    var targetView: ImageView? = null // 目标ImageView
    var resource: Any? = null // 加载资源
    var width = -1 // 指定宽度
    var height = -1 // 指定高度
    var isDiskCache = true // 磁盘缓存
    var isMemoryCache = true // 内存缓存

    @DrawableRes
    var placeholder: Int = -1 // 占位图资源

    @DrawableRes
    var error: Int = -1 // 失败图资源

    var listener: Listener? = null

    companion object {
        fun create(): ImageOptions {
            return ImageOptions()
        }
    }

    fun with(targetObj: Any): ImageOptions {
        this.targetObj = targetObj
        return this
    }

    fun loadResource(resource: Any): ImageOptions {
        this.resource = resource
        return this
    }

    fun size(size: Int): ImageOptions {
        return size(width, height)
    }

    fun size(width: Int, height: Int): ImageOptions {
        this.width = width
        this.height = height
        return this
    }

    fun placeholder(@DrawableRes placeholder: Int): ImageOptions {
        this.placeholder = placeholder
        return this
    }

    fun error(@DrawableRes error: Int): ImageOptions {
        this.error = error
        return this
    }

    fun setDiskCache(isCache: Boolean): ImageOptions {
        isDiskCache = isCache
        return this
    }

    fun setMemoryCache(isCache: Boolean): ImageOptions {
        isMemoryCache = isCache
        return this
    }

    fun setListener(listener: Listener): ImageOptions {
        this.listener = listener
        return this
    }

    fun into(imageView: ImageView) {
        this.targetView = imageView
        ImageLoader.loadOptions(this)
    }

    interface Listener {
        fun onSuccess(model: Any?)
        fun onFail(model: Any?)
    }
}

实现Glide策略

class GlideLoader : ILoaderStrategy {
    private lateinit var requestManager: RequestManager

    override fun loadImage(options: ImageOptions) {
        requestManager = getRequestManager(options.targetObj)
        var requestBuilder: RequestBuilder<Drawable>? = null

        options.resource?.let {
            requestBuilder = generateRequestBuilder(it)
        }

        requestBuilder?.let {
            if (options.placeholder != -1) {
                it.placeholder(options.placeholder)
            }
            if (options.error != -1) {
                it.error(options.error)
            }
            if (options.width != -1 || options.height != -1) {
                it.override(options.width, options.height)
            }
            it.skipMemoryCache(options.isMemoryCache)
            it.diskCacheStrategy(if (options.isDiskCache) DiskCacheStrategy.AUTOMATIC else DiskCacheStrategy.NONE)
            options.listener?.let { listener ->
                it.addListener(object : RequestListener<Drawable> {
                    override fun onLoadFailed(
                        e: GlideException?,
                        model: Any?,
                        target: Target<Drawable>?,
                        isFirstResource: Boolean
                    ): Boolean {
                        listener.onFail(model)
                        return false
                    }

                    override fun onResourceReady(
                        resource: Drawable?,
                        model: Any?,
                        target: Target<Drawable>?,
                        dataSource: DataSource?,
                        isFirstResource: Boolean
                    ): Boolean {
                        listener.onSuccess(model)
                        return false
                    }
                })
            }
            if (options.targetView == null) {
                throw IllegalArgumentException("targetView cannot be null");
            }
            it.into(options.targetView!!)
        }
    }

    private fun getRequestManager(targetObj: Any?): RequestManager {
        return if (targetObj is FragmentActivity) {
            Glide.with(targetObj)
        } else if (targetObj is Context) {
            Glide.with(targetObj)
        } else if (targetObj is View) {
            Glide.with(targetObj)
        } else if (targetObj is Fragment) {
            Glide.with(targetObj)
        } else {
            throw IllegalArgumentException("You cannot start a load on a null Context");
        }
    }

    private fun generateRequestBuilder(res: Any): RequestBuilder<Drawable>? {
        return if (res is String) {
            requestManager.load(res)
        } else if (res is File) {
            requestManager.load(res)
        } else {
            return null
        }
    }

    override fun clearDiskCache(context: Context) {
        thread {
            Glide.get(context).clearDiskCache()
        }
    }

    override fun clearMemoryCache(context: Context) {
        Glide.get(context).clearMemory()
    }

    override fun clear(imageView: ImageView) {
        Glide.with(imageView.context).clear(imageView)
    }
}

图片管理类

object ImageLoader {

    private var imageLoader: ILoaderStrategy? = null

    fun setImageLoader(imageLoader: ILoaderStrategy) {
        this.imageLoader = imageLoader
    }

    fun with(targetObj: Any): ImageOptions {
        val options = ImageOptions.create()
        options.with(targetObj)
        return options
    }

    fun loadOptions(options: ImageOptions) {
        imageLoader!!.loadImage(options)
    }

    fun clearDiskCache(context: Context){
        imageLoader!!.clearDiskCache(context)
    }

    fun clearMemoryCache(context: Context){
        imageLoader!!.clearMemoryCache(context)
    }

    fun clearAll(context:Context){
        imageLoader!!.clearAll(context)
    }

    fun clear(imageView: ImageView){
        imageLoader!!.clear(imageView)
    }

}

使用

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_image_loader)
    imageView0 = findViewById(R.id.imageView0)
    imageView1 = findViewById(R.id.imageView1)
    imageView2 = findViewById(R.id.imageView2)

    ImageLoader.setImageLoader(GlideLoader())

    val url = "https://i-blog.csdnimg.cn/blog_migrate/de6e3262387d57977e53af596a87f582.png"

    ImageLoader.with(this)
        .loadResource(url)
        .size(100)
        .placeholder(R.mipmap.ic_launcher)
        .error(R.mipmap.ic_launcher)
        .into(imageView1)

    ImageLoader.with(this)
        .loadResource(File(cacheDir, "aaa.png"))
        .placeholder(R.mipmap.ic_launcher)
        .error(R.mipmap.ic_launcher)
        .into(imageView2)
} 
ImageLoader.clear(imageView1)
ImageLoader.clearAll(this)
ImageLoader.clearMemoryCache(this)
ImageLoader.clearDiskCache(this)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/875005.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络视频流解码显示后花屏问题的分析

问题描述 rtp打包的ps视频流发送到客户端后显示花屏。 数据分析过程 1、用tcpdump抓包 tcpdump -i eth0 -vnn -w rtp.pcap 2、用wireshark提取rtp的payload 保存为record.h264文件 3、用vlc播放器播放 显示花屏 4、提取关键帧 用xxd命令将h264文件转为txt文件 xxd -p…

KEIL中编译51程序 算法计算异常的疑问

KEIL开发 51 单片机程序 算法处理过程中遇到的问题 ...... by 矜辰所致前言 因为产品的更新换代&#xff0c; 把所有温湿度传感器都换成 SHT40 &#xff0c;替换以前的 SHT21。在 STM32 系列产品上的替换都正常&#xff0c;但是在一块 51 内核的无线产品上面&#xff0c;数据…

STM32-HAL库开发快速入门

注:本文主要记录一下STM32CubeMX软件的使用流程,记录内容以STM32外设&#xff08;中断、I2C、USART、SPI等配置&#xff09;在STM32CubeMX中的设置为主&#xff0c;对驱动代码编写不做记录&#xff0c;所以阅读本文最好有标准库开发经验。除第2节外&#xff0c;使用的都是韦东山…

C++的流提取(>>)(输入) 流插入(<<)(输出)

什么是输入和输出流 流提取&#xff08;<<&#xff09;(输入) 理解&#xff1a;我们可以理解为&#xff0c;输入到io流里面&#xff0c;比如是cin&#xff0c;然后从输入流中读取数据 流插入&#xff08;<<&#xff09;&#xff08;输出&#xff09; 理解&#xff…

网络协议头分析

目录 数据的传输与封装过程 以太网完整帧 以太网头部 IP头 TCP头 数据的传输与封装过程 以太网完整帧 ● 对于网络层最大数据帧长度是1500字节 ● 对于链路层最大数据长度是1518字节&#xff08;150014CRC&#xff09;● 发送时候&#xff0c;IP层协议栈程序检测到发送数…

前端 + 接口请求实现 vue 动态路由

前端 接口请求实现 vue 动态路由 在 Vue 应用中&#xff0c;通过前端结合后端接口请求来实现动态路由是一种常见且有效的权限控制方案。这种方法允许前端根据用户的角色和权限&#xff0c;动态生成和加载路由&#xff0c;而不是在应用启动时就固定所有的路由配置。 实现原理…

路由器的固定ip地址是啥意思?固定ip地址有什么好处

‌在当今数字化时代&#xff0c;‌路由器作为连接互联网的重要设备&#xff0c;‌扮演着举足轻重的角色。‌其中&#xff0c;‌路由器的固定IP地址是一个常被提及但可能让人困惑的概念。‌下面跟着虎观代理小二一起将深入探讨路由器的固定IP地址的含义&#xff0c;‌揭示其背后…

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:下(人物动画)

上个博客我们做出了人物的动画机和人物移动跳跃&#xff0c;接下来我们要做出人物展现出来的动画了 我们接下来就要用到动画机了&#xff0c;双击我们的动画机&#xff0c;进入到这样的页面&#xff0c;我这是已经做好的页面&#xff0c;你们是没有这些箭头的 依次像我一样连接…

【Python】Windows下python的下载安装及使用

文章目录 下载安装检测 使用环境搭建下载PycharmPycharm安装 下载 进入官网下载&#xff1a;https://www.python.org/ 点击下载 64位电脑下载该项 安装 勾选 添加至环境变量 使用自定义安装 检测 安装成功后&#xff0c;打开命令提示符窗口&#xff08;winR,输入cmd回车…

红海云 × 紫光同芯 | 数字化驱动芯片领军企业人力资源管理新升级

紫光同芯微电子有限公司&#xff08;以下简称“紫光同芯”&#xff09;是新紫光集团汽车电子与智能芯片板块的核心企业。专注于汽车电子与安全芯片领域&#xff0c;累计出货超过230亿颗&#xff0c;为亚洲、欧洲、美洲、非洲的二十多个国家和地区提供产品和服务。 为进一步提升…

VSC++: 十转十六进制

void 十转十六进制(int 数) {//缘由https://ask.csdn.net/questions/1089023string 十六模 "0123456789ABCDEF", 进制 "";int j 0;cout << 数 << ends; if (!数)cout << "0";while (数)进制.push_back(十六模[数 % 16]), j…

LCS—最长公共子序列

最长公共子序列问题就是求出两个字符串的LCS长度&#xff0c;是一道非常经典的面试题目&#xff0c;因为它的解法是典型的二维动态规划。 比如输入 str1 "babcde", str2 "acbe"&#xff0c;算法应该输出3&#xff0c;因为 str1 和 str2 的最长公共子序列…

【大模型基础】P2 Bag-of-Words

目录 词袋模型 概述词袋模型 实例第1步 构建语料库第2步 对句子进行分词第3步 创建词汇表第4步 转换词袋表示第5步 计算余弦相似度 词袋模型的局限性 词袋模型 概述 词袋模型&#xff0c;Bag-of-Words&#xff0c;是一种简单的文本表示方法&#xff0c;也是 NLP 中的一个经典模…

[数据集][目标检测]血细胞检测数据集VOC+YOLO格式2757张4类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2757 标注数量(xml文件个数)&#xff1a;2757 标注数量(txt文件个数)&#xff1a;2757 标注…

因MathType导致word复制粘贴失败,显示:运行时错误‘53’

问题&#xff1a;运行时错误‘53’&#xff1a;文件未找到&#xff1a;MathPage.WLL 解决方法&#xff1a;打开MathType所在文件夹 右击MathType图标->点击“打开文件所在位置”->找到MathPage.WLL文件。 然后&#xff0c;把这个文件复制到该目录下&#xff1a;C:\Progr…

jenkins工具的介绍和gitlab安装

使用方式 替代手动&#xff0c;自动化拉取、集成、构建、测试&#xff1b;是CI/CD持续集成、持续部署主流开发模式中重要工具&#xff1b;必须组件 jenkins-gitlab&#xff0c;代码公共仓库服务器&#xff08;至少6G内存&#xff09;&#xff1b;jenkins-server&#xff0c;需…

论文解读:利用大模型进行基于上下文的OCR校正

论文地址&#xff1a;https://arxiv.org/pdf/2408.17428 背景概述 研究问题&#xff1a;这篇文章要解决的问题是如何利用预训练的语言模型&#xff08;LMs&#xff09;来改进光学字符识别&#xff08;OCR&#xff09;的质量&#xff0c;特别是针对报纸和期刊等复杂布局的文档。…

Jmeter_循环获取请求接口的字段,并写入文件

通过JSON提取器、计数器、beanshell&#xff0c;循环读取邮箱接口的返回字段&#xff0c;筛选出flag为3的收件人&#xff0c;并写入csv文件。 1、调用接口&#xff0c;获取所有的邮件$.data.total.count&#xff1b; 2、beanshell后置处理total转换成页码&#xff0c;这里是227…

纵切车床和走心机的区别

纵切车床和走心机在机床加工领域中各自扮演着重要的角色&#xff0c;它们在多个方面存在显著的差异。下面&#xff0c;我将从基本概念、工作原理、应用领域以及加工能力等方面来详细阐述这两者的区别。 一.基本概念 ‌纵切车床‌&#xff1a;纵切车床&#xff0c;也被称为自动纵…

NFTScan | 09.02~09.08 NFT 市场热点汇总

欢迎来到由 NFT 基础设施 NFTScan 出品的 NFT 生态热点事件每周汇总。 周期&#xff1a;2024.09.02~ 2024.09.08 NFT Hot News 01/ 数据&#xff1a;NFT 8 月销售额跌破 4 亿美元&#xff0c;创年内新低 9 月 2 日&#xff0c;数据显示&#xff0c;8 月 NFT 的月销售额仅为 …