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