当前位置: 首页 > article >正文

android Recyclerview viewholder统一封装

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.kler.cn/a/505645.html

相关文章:

  • 探索 Transformer²:大语言模型自适应的新突破
  • Go语言中http.Transport的Keep-Alive配置与性能优化方法
  • SpringAOP前置——代理模式
  • 升级 SpringBoot3 全项目讲解 — 为什么 SpringBoot3 应该抛弃 Maven,搭配 Gradle 来使用?
  • Linux内核的启动
  • 用Guiguider生成的字体代替LVGL默认字体
  • Android Auto能够与Android设备整合的几项功能有哪些?
  • PostgreSQL-WAL日志介绍(二)
  • STM32-笔记43-低功耗
  • 机器学习(2):线性回归Python实现
  • npm更换淘宝镜像源
  • AI 编程工具—Cursor进阶使用 阅读开源项目
  • 2025网络架构
  • HTML5 Canvas实现的跨年烟花源代码
  • 【conda】迁移到其他ubuntu机器
  • OSPF - 特殊报文与ospf的机制
  • replaceState和vue的router.replace删除query参数的区别
  • 无人机航拍价格 航拍价格
  • 内存快照:宕机后Redis如何实现快速恢复?
  • 基于RFM聚类与随机森林算法的智能手机用户监测数据案例分析
  • Shell脚本一键推送到钉钉告警并@指定人
  • Nginx 如何设置 Upgrade-Insecure-Requests 报头 ?
  • python tkinter做界面 SDK打开海康工业相机,callback取图,halcon显示
  • 一文了解如何使用 DBeaver 管理 DolphinDB
  • 1_CSS3 边框 --[CSS3 进阶之路]
  • 计算机网络-数据链路层(虚拟局域网VLAN)