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