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 // 目标ImageViewvar resource: Any? = null // 加载资源var width = -1 // 指定宽度var height = -1 // 指定高度var isDiskCache = true // 磁盘缓存var isMemoryCache = true // 内存缓存@DrawableResvar placeholder: Int = -1 // 占位图资源@DrawableResvar error: Int = -1 // 失败图资源var listener: Listener? = nullcompanion object {fun create(): ImageOptions {return ImageOptions()}}fun with(targetObj: Any): ImageOptions {this.targetObj = targetObjreturn this}fun loadResource(resource: Any): ImageOptions {this.resource = resourcereturn this}fun size(size: Int): ImageOptions {return size(width, height)}fun size(width: Int, height: Int): ImageOptions {this.width = widththis.height = heightreturn this}fun placeholder(@DrawableRes placeholder: Int): ImageOptions {this.placeholder = placeholderreturn this}fun error(@DrawableRes error: Int): ImageOptions {this.error = errorreturn this}fun setDiskCache(isCache: Boolean): ImageOptions {isDiskCache = isCachereturn this}fun setMemoryCache(isCache: Boolean): ImageOptions {isMemoryCache = isCachereturn this}fun setListener(listener: Listener): ImageOptions {this.listener = listenerreturn this}fun into(imageView: ImageView) {this.targetView = imageViewImageLoader.loadOptions(this)}interface Listener {fun onSuccess(model: Any?)fun onFail(model: Any?)}
}
实现Glide策略
class GlideLoader : ILoaderStrategy {private lateinit var requestManager: RequestManageroverride fun loadImage(options: ImageOptions) {requestManager = getRequestManager(options.targetObj)var requestBuilder: RequestBuilder<Drawable>? = nulloptions.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? = nullfun 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)
相关文章:
Android 优雅封装Glide
文章目录 Android 优雅封装Glide核心思想定义策略接口定义图片选项实现Glide策略图片管理类使用 Android 优雅封装Glide 核心思想 使用策略模式实现不同图片加载框架的切换,使用建造者设计模式处理不同参数,最后通过 ImageLoader 进行管理。 定义策略…...
智能优化算法-粒子群优化算法(PSO)(附源码)
目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1.内容介绍 粒子群优化算法 (Particle Swarm Optimization, PSO) 是一种基于群体智能的元启发式优化算法,由Kennedy和Eberhart于1995年提出。PSO模拟了鸟群或鱼群的觅食行为,通过粒子之间的相互作用…...
vue系统获取授权平台授权码实现单点登录、注销功能
公司平台需要对接别的平台 实现单点登录 注销。简而言之,不需要在自己公司系统登录 统一在别的平台登录后获取到登录凭证(授权码) 在本公司系统实现免密登录的功能。 流程: 跳转授权页面和保存授权码的代码: hrefLog…...
Java之枚举
目录 枚举 引入 定义 代码示例 常用方法 代码示例 枚举的优缺点 枚举和反射 面试题 枚举 引入 枚举是在JDK1.5以后引入的。主要用途是:将一组常量组织起来,在这之前表示一组常量通常使用定义常量的方式: publicstaticintfinalRED1;…...
八、适配器模式
适配器模式(Adapter Pattern)是一种结构型设计模式,它允许不兼容的接口之间进行合作。适配器模式通过创建一个适配器类来转换一个接口的接口,使得原本由于接口不兼容无法一起工作的类可以一起工作。 主要组成部分: 目标…...
关于E-R图
一 什么是E-R图 E-R图(Entity-Relationship Diagram)是一种数据建模工具,用于描述数据库中实体之间的关系。它使用实体(Entity)、属性(Attribute)和关系(Relationship&#…...
DVWA通关教程
Brute Force Low 先进行一下代码审计 <?php // 检查是否通过GET请求传递了Login参数(注意:这里应该是username或类似的,但代码逻辑有误) if( isset( $_GET[ Login ] ) ) { // 从GET请求中获取用户名 $user $_GET[ us…...
网络学习-eNSP配置VRRP
虚拟路由冗余协议(Virtual Router Redundancy Protocol,简称VRRP) VRRP广泛应用在边缘网络中,是一种路由冗余协议,它的设计目标是支持特定情况下IP数据流量失败转移不会引起混乱,允许主机使用单路由器,以及即使在实际…...
Kafka【九】如何实现数据的幂等性操作
为了解决Kafka传输数据时,所产生的数据重复和乱序问题,Kafka引入了幂等性操作,所谓的幂等性,就是Producer同样的一条数据,无论向Kafka发送多少次,kafka都只会存储一条。注意,这里的同样的一条数…...
JavaScript知识点1
目录 1.JavaScript中常用的数组方法有哪些? 2.JavaScript的同源策略? 3.JavaScript中的 NaN 是什么? 4.JavaScript中的split、slice、splice函数区别? 1.JavaScript中常用的数组方法有哪些? 在 JavaScript 中&…...
51单片机个人学习笔记11(AT24C02-I2C总线)
前言 本篇文章属于STC89C52单片机(以下简称单片机)的学习笔记,来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记,只能做参考,细节方面建议观看视频,肯定受益匪浅。 [1-1] 课程简介_哔哩…...
创建Java项目,可实现main方法运行,实现对性能数据的处理
1、Android Studio无法执行Java类的main方法问题及解决方法 Android Studio无法执行Java类的main方法问题及解决方法_delegatedbuild-CSDN博客 D:\workspaces\performanceTools\.idea 文件夹下,gardle.xml ,添加依赖 <option name"delegatedBuild"…...
JavaWeb(后端)
MVC MVC 就是 Model View Controller 的缩写,属于一种软件架构设计模式一种思想,把我们的项目分为控制器(Controller)、模型(Model)、视图(view)三个部分,model就是处理…...
828华为云征文 | 华为云Flexusx实例,高效部署Servas书签管理工具的优选平台
前言 华为云Flexus X实例,Servas书签管理工具部署的优选平台!828节日特惠,让高效管理您的知识宝藏触手可及。Flexus X实例以其卓越的算力、灵活的资源配置和智能调优技术,为Servas提供了稳定、高效的运行环境。无论是快速访问、安…...
分治法和动态规划法
一、分治法(Divide and Conquer) 定义 分治法是一种将大问题分解成若干个小问题,递归地解决这些小问题,然后将这些小问题的解合并起来得到原问题的解的算法策略。(子问题之间相互独立) 基本步骤 1.分解…...
【FreeRL】我的深度学习库构建思想
文章目录 前言参考python环境效果已复现结果 综述DQN.py(主要)算法实现参数修改细节实现显示训练,保存训练 Buffer.pyevaluate.pylearning_curves 前言 代码实现在:https://github.com/wild-firefox/FreeRL 欢迎star 参考 动手学强化学习e…...
Docker部署nginx容器无法访问80端口
问题说明 在阿里云ECS服务器上部署一台CentOS服务器,然后在里面安装了docker服务。用docker部署了nginx,开启docker中的nginx服务,映射宿主机端口80 把阿里云服务器上面的安全组放开了80端口 但是还是无法访问nginx的80web界面 问题分析 查…...
Python语言开发学习之使用Python预测天气
什么是wttr? 使用Python预测天气的第一步,我们要了解wttr是什么。wttr.in是一个面向控制台的天气预报服务,它支持各种信息表示方法,如面向终端的ANSI序列(用于控制台HTTP客户端(curl、httpie或wget))、HTML(用于web浏览器)或PNG(…...
minio实现大文件断点续传
最近工作中遇到一个需求,用户需要上传大文件几百M,为了更好的用户体验,需要支持断点续传,秒传,上传进度条等功能。需求如下: 方案有两种: 第一种:前端直接将整个大文件丢到后端&…...
Qt绘制动态仪表(模仿汽车仪表指针、故障灯)
背景: 项目需要,可能需要做一些仪表显示。此篇除了介绍实现方法,还要说明心路历程。对我而言,重要的是心理,而不是技术。写下来也是自勉。 本人起初心里是比较抵触的,从业20多年了,深知所谓界…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
免费批量Markdown转Word工具
免费批量Markdown转Word工具 一款简单易用的批量Markdown文档转换工具,支持将多个Markdown文件一键转换为Word文档。完全免费,无需安装,解压即用! 官方网站 访问官方展示页面了解更多信息:http://mutou888.com/pro…...
华为云Flexus+DeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手
华为云FlexusDeepSeek征文 | 基于Dify构建具备联网搜索能力的知识库问答助手 一、构建知识库问答助手引言二、构建知识库问答助手环境2.1 基于FlexusX实例的Dify平台2.2 基于MaaS的模型API商用服务 三、构建知识库问答助手实战3.1 配置Dify环境3.2 创建知识库问答助手3.3 使用知…...
信息系统分析与设计复习
2024试卷 单选题(20) 1、在一个聊天系统(类似ChatGPT)中,属于控制类的是()。 A. 话语者类 B.聊天文字输入界面类 C. 聊天主题辨别类 D. 聊天历史类 解析 B-C-E备选架构中分析类分为边界类、控制类和实体类。 边界…...
