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")
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值