android Recyclerview viewholder统一封装

news2025/2/5 16:48:08

Recyclerview holder 统一封装 ViewHolder类

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.os.CountDownTimer
import android.util.SparseArray
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.recyclerview.widget.RecyclerView
import com.tongtong.feat_watch.utils.WGlide


/**
 * @author: shuhuai
 * @desc:
 * @date: 2024/11/15
 * @version:
 * @remark
 */
open class ViewHolder(itemView: View?) : RecyclerView.ViewHolder(
    itemView!!
) {
    private var countDownTimer: CountDownTimer? = null

    //用于缓存已找的界面
    private val mView = SparseArray<View>()
    fun <T : View?> getView(viewId: Int): T? {
        //对已有的view做缓存
        var view = mView[viewId]
        //使用缓存的方式减少findViewById的次数
        if (view == null) {
            view = itemView.findViewById(viewId)
            mView.put(viewId, view)
        }
        return view as T?
    }

    fun startCountDown(
        viewId: Int,
        remainingTime: Long,
        copywrit: String? = "",
        unit: TimeUnit = TimeUnit.SECOND,
        backgroundColor: String = "00000000",
        callback: (message: String?) -> Unit = { }
    ) {

        val view = getView<TextView>(viewId)!!
        countDownTimer = object : CountDownTimer(remainingTime, unit.v) {
            @RequiresApi(Build.VERSION_CODES.S)
            override fun onTick(millisUntilFinished: Long) {
                view.apply {
                    text = TimeUnit.formatTime(millisUntilFinished, unit) + copywrit
                    val bg = background as GradientDrawable
                    val code = String.format("#%s", backgroundColor)
                    bg.setColor(Color.parseColor(code))
                }
            }

            override fun onFinish() {
                callback.invoke("倒计时结束")
            }
        }.start()
    }

    fun cancelCountDown() {
        if (countDownTimer != null) {
            countDownTimer!!.cancel()
        }
    }

    fun destoryDown() {
        cancelCountDown()
        countDownTimer = null
    }

    //通用的功能进行封装  设置文本 设置条目点击事件  设置图片
    fun setText(viewId: Int, text: CharSequence?): ViewHolder {
        val view = getView<TextView>(viewId)!!
        view.text = text
        //希望可以链式调用
        return this
    }

    //通用的功能进行封装  设置文本 设置条目点击事件  设置图片
    fun setText(viewId: Int, text: String?): ViewHolder {
        val view = getView<TextView>(viewId)!!
        view.text = text
        //希望可以链式调用
        return this
    }

    fun setTextColor(viewId: Int, color: Int): ViewHolder {
        val view = getView<TextView>(viewId)!!
        view.setTextColor(color)
        //希望可以链式调用
        return this
    }

    fun setTextBackground(viewId: Int, color: Int): ViewHolder {
        val view = getView<TextView>(viewId)!!
        view.setBackgroundColor(color)
        //希望可以链式调用
        return this
    }

    fun setTextTypeface(viewId: Int, style: Int): ViewHolder {
        val view = getView<TextView>(viewId)!!
        view.setTypeface(null, style)
        //希望可以链式调用
        return this
    }

    fun setSelected(viewId: Int, selected: Boolean): ViewHolder {
        val view = getView<TextView>(viewId)!!
        view.isSelected = selected
        //希望可以链式调用
        return this
    }

    fun setSelected2(viewId: Int, selected: Boolean): ViewHolder {
        val view = getView<View>(viewId)!!
        view.isSelected = selected
        return this
    }

    fun setVisible(viewId: Int, visible: Boolean): ViewHolder {
        val view = getView<View>(viewId)!!
        view.visibility = if (visible) View.VISIBLE else View.GONE
        return this
    }

    fun setVisible(viewId: Int, visible: Boolean, isLocation: Boolean): ViewHolder {
        val view = getView<View>(viewId)!!
        if (isLocation) {
            view.visibility = if (visible) View.VISIBLE else View.INVISIBLE
        } else {
            view.visibility = if (visible) View.VISIBLE else View.GONE
        }

        return this
    }

    /**
     * 设置本地图片
     * @param viewId
     * @param resId
     * @return
     */
    fun setImageResource(viewId: Int, resId: Int): ViewHolder {
        val iv = getView<ImageView>(viewId)!!
        iv.setImageResource(resId)
        return this
    }

    fun setDrawable(mContext: Context?, viewId: Int, resId: Int): ViewHolder {
        val v = getView<View>(viewId)!!
        v.setBackgroundDrawable(mContext?.resources?.getDrawable(resId))
        return this
    }

    fun setTextSelected(viewId: Int, bool: Boolean): ViewHolder {
        val tv = getView<TextView>(viewId)!!
        tv.isSelected = bool
        return this
    }

    /**
     * 设置本地图片
     * @param viewId
     * @param resId
     * @return
     */
    fun setImageDrawable(mContext: Context, viewId: Int, resId: Int): ViewHolder {
        val iv = getView<ImageView>(viewId)!!
        iv.setImageDrawable(mContext.getResources().getDrawable(resId))
        return this
    }

    /**
     * 加载图片资源路径
     * @param viewId
     * @param imageLoader
     * @return
     */
    fun setImagePath(viewId: Int, imageLoader: HolderImageLoader, res: Int): ViewHolder {
        val iv = getView<ImageView>(viewId)!!
        imageLoader.loadImage(iv, imageLoader.path, res)
        return this
    }

    fun setImageGrey(mContext: Context?, viewId: Int, url: String?): ViewHolder {
        val view = getView<ImageView>(viewId)!!
        WGlide.setImageGrey(mContext, view, url)
        return this
    }

    fun setImage(mContext: Context?, viewId: Int, url: String?): ViewHolder {
        val view = getView<ImageView>(viewId)!!
        WGlide.setImage(mContext, view, url)
        return this
    }

    fun setImage(mContext: Context?, viewId: Int, url: String?, res: Int): ViewHolder {
        val view = getView<ImageView>(viewId)!!
        WGlide.setImage(mContext, view, url)
        return this
    }

    fun setImage(
        mContext: Context?,
        viewId: Int,
        url: String?,
        width: Int?,
        height: Int?
    ): ViewHolder {
        val view = getView<ImageView>(viewId)!!
        WGlide.setImage(mContext, view, url, width, height)
        return this
    }

    fun setImageRadius(
        mContext: Context?,
        viewId: Int,
        url: String?,
        radius: Float = 0f,
    ): ViewHolder {
        val view = getView<ImageView>(viewId)!!
        WGlide.setImageRadius(mContext, view, url, radius)
        return this
    }

    fun setImageRadiusForTop(
        mContext: Context?,
        viewId: Int,
        url: String?,
        radiusTL: Float = 0f,
        radiusTR: Float = 0f,
    ): ViewHolder {
        val view = getView<ImageView>(viewId)!!
        WGlide.setImageRadius(mContext, view, url, 0f, radiusTL, radiusTR)
        return this
    }

    @SuppressLint("NewApi")
    fun setBackground(mContext: Context, viewId: Int, bg: Int): ViewHolder {
        val tv = getView<View>(viewId) as TextView
        tv.background = mContext.getResources().getDrawable(bg)
        return this
    }

    /**
     * 关于事件的
     */
    fun setOnClickListener(viewId: Int, listener: View.OnClickListener?): ViewHolder {
        val view = getView<View>(viewId)!!
        view.setOnClickListener(listener)
        return this
    }

    abstract class HolderImageLoader(mContext: Context, var path: String) {
        var mContext: Context = mContext

        /**
         * 需要去复写这个方法加载图片
         * @param iv
         * @param path
         */
        abstract fun loadImage(iv: ImageView?, path: String?, res: Int)
    }
}

enum class TimeUnit(val v: Long) {
    DAY(24 * 60 * 60 * 1000),
    HOUR(60 * 60 * 1000),
    MINUTE(60 * 1000),
    HOUR_UN_SECOND(60 * 1000),
    HOUR_UN_SECOND_NO_ZERO(1000),
    SECOND(1000);

    companion object {
        fun formatTime(millis: Long, unit: TimeUnit): String {
            val totalSeconds: Long = millis / 1000
            val days: Long = totalSeconds / (24 * 3600) // 每天86400秒,24*3600
            val hours: Long = (totalSeconds % (24 * 3600)) / 3600 // 取余后计算小时
            val minutes: Long = (totalSeconds % 3600) / 60 // 取余后计算分钟
            val seconds: Long = totalSeconds % 60 // 取余后计算秒
            var time = "${days}${hours}${minutes}${seconds}秒"
            if (unit == HOUR) {
                time = "${(hours + days * 24)}${minutes}${seconds}秒"
            } else if (unit == MINUTE) {
                time = "${minutes + (hours + days * 24) * 60}${seconds}秒"
            } else if (unit == SECOND) {
                time = "${seconds + (minutes + (hours + days * 24) * 60) * 60}秒"
            } else if (unit == HOUR_UN_SECOND) {
                val _hour = hours + days * 24
                if (_hour > 0) {
                    time = "${(hours + days * 24)}${minutes}分"
                } else {
                    time = "${minutes}分"
                }
            } else if (unit == HOUR_UN_SECOND_NO_ZERO) {
                val _hour = hours + days * 24
                if (_hour > 0) {
                    time = "${(hours + days * 24)}${minutes}分"
                } else {
                    if (minutes > 0) {
                        time = "${minutes}分"
                    } else {
                        time = "${seconds}秒"
                    }
                }
            }
            return time;
        }
    }
}

具体实现

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.tongtong.feat_watch.R
import com.tongtong.feat_watch.ui.hall.bean.HallBean
import com.tongtong.feat_watch.ui.paly.view.scroll.ViewHolder

/**
 * @author: shuhuai
 * @desc:
 * @date: 2025/1/15
 * @version:
 * @remark
 */
class MyAdapter(context: Context?) :
    RecyclerView.Adapter<ViewHolder?>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder = ViewHolder(
            LayoutInflater.from(parent?.context).inflate(R.layout.fragment_hall, parent, false)
            )

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        TODO("Not yet implemented")
    }

    override fun getItemCount(): Int {
        TODO("Not yet implemented")
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

某政务行业基于 SeaTunnel 探索数据集成平台的架构实践

分享嘉宾&#xff1a;某政务公司大数据技术经理 孟小鹏 编辑整理&#xff1a;白鲸开源 曾辉 导读&#xff1a;本篇文章将从数据集成的基础概念入手&#xff0c;解析数据割裂给企业带来的挑战&#xff0c;阐述数据集成的重要性&#xff0c;并对常见的集成场景与工具进行阐述&…

【MySQL】使用C语言链接

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;MySQL 目录 一&#xff1a;&#x1f525; MySQL connect &#x1f98b; Connector / C 使用&#x1f98b; mysql 接口介绍&#x1f98b; 完整代码样例 二&#xff1a;&#x1f525; 共勉 一&#…

《Java核心技术II》并行流

并行流 从集合中获取并行流&#xff1a;Stream paralleWords words.parallelStream(); parallel方法将任意顺序流转换为并行流&#xff1a;Stream paralleWords Stream.of(wordArray).parallel(); 以下是不好的示范&#xff0c;假设对字符串的所有短单词计数&#xff1a; …

【Rust自学】13.2. 闭包 Pt.2:闭包的类型推断和标注

13.2.0. 写在正文之前 Rust语言在设计过程中收到了很多语言的启发&#xff0c;而函数式编程对Rust产生了非常显著的影响。函数式编程通常包括通过将函数作为值传递给参数、从其他函数返回它们、将它们分配给变量以供以后执行等等。 在本章中&#xff0c;我们会讨论 Rust 的一…

ETW HOOK[InfinityHook]技术解析

文章目录 概述分析过程参考资料 概述 ETW是操作系统为了对系统调用、异常等信息做了一个日志操作&#xff0c;本质就是在进行调用这些中断、异常、系统调用时会走向这个代码函数区域日志保存的功能。而ETW HOOK就是在驱动层微软的PatchGuard并未对其做到很好的检测&#xff0c…

码编译安装httpd 2.4,测试

下载链接&#xff1a;https://dlcdn.apache.org/httpd/httpd-2.4.62.tar.gz [rootopenEuler-1 ~]# yum install gcc gcc-c make -y [rootopenEuler-1 ~]# ll /root total 9648 -rw-------. 1 root root 920 Jan 10 17:15 anaconda-ks.cfg -rw-r--r-- 1 root root 9872432…

步入响应式编程篇(一)

响应式编程 为什么要有响应式编程&#xff1f;响应式编程的用法Flow api的用法处理器 为什么要有响应式编程&#xff1f; 传统编码&#xff0c;操作流程常见的是命令式编程范式&#xff0c;如对于一个请求或操作来说&#xff0c;都是串行执行&#xff0c;直到异常或执行结束&a…

C++—18、C++ 中如何写类

一、类的功能阐述 今天我们将用目前学到的类的基础知识从头开始编写一个类。只编写一个基本的Log类&#xff0c;来演示到目前为止我们学过的一些基本特性。随着接下来的学习你会看到从一个类的基本版本到一个更高级版本的过程和区别。高级版本可以做同样的事情&#xff0c;但可…

SW - 查看装配图中的零件的全路径名称

文章目录 SW - 查看装配图中的零件的全路径名称概述笔记END SW - 查看装配图中的零件的全路径名称 概述 装配图中&#xff0c;如果本机有多个不同版本的同名零件(e.g. v1/p1零件, v2/p1零件)&#xff0c;在装配图中想确认是哪个版本的零件。 如果编辑错了文件&#xff0c;或者…

【开源分享】nlohmann C++ JSON解析库

文章目录 1. Nlohmann JSON 库介绍2. 编译和使用2.1 获取库2.2 包含头文件2.3 使用示例2.4 编译 3. 优势4. 缺点5. 总结参考 1. Nlohmann JSON 库介绍 Nlohmann JSON 是一个用于 C 的现代 JSON 库&#xff0c;由 Niels Lohmann 开发。它以易用性和高性能著称&#xff0c;支持 …

神经网络基础-正则化方法

文章目录 1. 什么是正则化2. 正则化方法2.1 Dropout正则化2.2 批量归一化(BN层) 学习目标&#xff1a; 知道正则化的作用掌握随机失活 DropOut 策略知道 BN 层的作用 1. 什么是正则化 在设计机器学习算法时希望在新样本上的泛化能力强。许多机器学习算法都采用相关的策略来减小…

【C++】面试题整理(未完待续)

【C】面试题整理 文章目录 一、概述二、C基础2.1 - 指针在 32 位和 64 位系统中的长度2.2 - 数组和指针2.3 - 结构体对齐补齐2.4 - 头文件包含2.5 - 堆和栈的区别2.6 - 宏函数比较两个数值的大小2.7 - 冒泡排序2.8 - 菱形继承的内存布局2.9 - 继承重写2.10 - 如何禁止类在栈上分…

ASP.NET Core - 依赖注入(四)

ASP.NET Core - 依赖注入&#xff08;四&#xff09; 4. ASP.NET Core默认服务5. 依赖注入配置变形 4. ASP.NET Core默认服务 之前讲了中间件&#xff0c;实际上一个中间件要正常进行工作&#xff0c;通常需要许多的服务配合进行&#xff0c;而中间件中的服务自然也是通过 Ioc…

w~Transformer~合集11

我自己的原文哦~ https://blog.51cto.com/whaosoft/12472192 #LightSeq 最高加速9倍&#xff01;字节跳动开源8比特混合精度Transformer引擎,近年来&#xff0c;Transformer 已经成为了 NLP 和 CV 等领域的主流模型&#xff0c;但庞大的模型参数限制了它的高效训练和推理。…

海云安开发者安全智能助手D10荣膺 “ AI标杆产品 ” 称号,首席科学家齐大伟博士入选2024年度 “ 十大杰出青年 ”

2024年12月27日&#xff0c;粤港澳大湾区AI领袖峰会在深圳成功举办&#xff0c;大会表彰了在人工智能技术创新、应用实践和产业发展等方面取得优异成绩的企业和个人&#xff0c;深圳海云安网络安全技术有限公司开发者安全智能助手D10荣膺“AI标杆产品”称号。同时&#xff0c;公…

Autodl转发端口,在本地机器上运行Autodl服务器中的ipynb文件

通过 SSH 隧道将远程端口转发到本地机器 输入服务器示例的SSH指令和密码&#xff0c;将远程的6006端口代理到本地 在服务器终端&#xff0c;激活conda虚拟环境 conda activate posecnnexport PYOPENGL_PLATFORMegljupyter notebook --no-browser --port6006 --allow-root从…

网站建设公司哪家好?我的避坑指南

公司刚成立那个时候&#xff0c;第一步就是想着抓紧做一个官网&#xff0c;因为一个好的网站可以通过互联网源源不断的带来客流&#xff0c;所以小公司业务最重要&#xff0c;我就赶紧在网上开始找公司。 网站是的大活&#xff0c;对于我这种什么都不会的&#xff0c;当然只能…

浅谈云计算15 | 存储可靠性技术(RAID)

存储可靠性技术 一、存储可靠性需求1.1 数据完整性1.2 数据可用性1.3 故障容错性 二、传统RAID技术剖析2.1 RAID 02.2 RAID 12.3 RAID 52.4 RAID 62.5 RAID 10 三、RAID 2.0技术3.1 RAID 2.0技术原理3.1.1 两层虚拟化管理模式3.1.2 数据分布与重构 3.2 RAID 2.0技术优势3.2.1 自…

qml RadialGradient详解

1、概述 RadialGradient是QML中用于创建径向渐变效果的一种类型。它允许您定义从中心向外辐射的颜色渐变&#xff0c;可以应用于各种QML可视组件上&#xff0c;如Rectangle、Image等&#xff0c;以创建出丰富的视觉效果。 2、重要属性 angle&#xff1a;定义渐变围绕其中心点…

链表 -- 反转链表,k个一组翻转链表,两两交换链表中结点

目录 反转链表 题目 ​编辑 分析 代码 k个一组翻转链表 题目 分析 代码 两两交换链表中的结点 题目 ​编辑 分析 代码 反转链表 题目 分析 反转过程: newhead作为遍历指针,最终停在尾结点上prev保存上一个结点,通过改变newhead和prev的连接来实现反转(核心)通过ne…