自学内容网 自学内容网

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")
    }
}

原文地址:https://blog.csdn.net/NotesChapter/article/details/145157717

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!