最近在项目中使用Recycler,觉得每次使用都得从头开始些Adapter,所以自己封装了一个,刚刚开始:其实其中的思想就是把数据的处理和View分开处理,所以我想把所有有关View的操作都抽取到BaseViewHolder中,而BaseAdapter做鱼数据相关操作,这样我们在使用的时候仅仅只要关注Adapter即可。使用Adapter时我们只是为了绑定数据,,所以一些基本的操作,都可以放在BaseAdapter去做;
/**
* VH : ViewHolder
* D:数据类型
*/
abstract class BaseAdapter<T : BaseViewHolder, D>(
var mDataSets: MutableList<D>? = null, @LayoutRes val mItemLayoutId: Int = 0) : RecyclerView.Adapter<T>() {
private var mOnItemClickListener: OnItemClickListener? = null
fun setOnItemClickListener(onItemClickListener: OnItemClickListener) {
this.mOnItemClickListener = onItemClickListener
}
@Suppress("UNCHECKED_CAST")
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): T {
val view = LayoutInflater
.from(parent.context)
.inflate(mItemLayoutId, parent, false)
val clazz = createBaseViewHolder()
val constructor = clazz?.getDeclaredConstructor(View::class.java)
constructor?.isAccessible = true
return constructor?.newInstance(view) as T
}
/**
*由于类型擦除可能引起强转异常,使用反射
*/
private fun createBaseViewHolder(): Class<*>? {
val type = javaClass.genericSuperclass
if (type is ParameterizedType) {
type.actualTypeArguments.forEach {
if (it is Class<*>) {
if (BaseViewHolder::class.java.isAssignableFrom(it)) {
return it
}
} else if (it is ParameterizedType) {
if (it.rawType is Class<*> && BaseViewHolder::class.java.isAssignableFrom(it as Class<*>?)) {
return it
}
}
}
}
return null
}
override fun getItemCount(): Int = mDataSets?.size ?: 0
override fun onBindViewHolder(holder: T, position: Int) {
convert(holder, mDataSets?.get(position))
holder.itemView?.setOnClickListener {
mOnItemClickListener?.onItemClick(it, position)
}
}
abstract fun convert(holder: T, data: D?)
}
ViewHolder:
open class BaseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
其中BaseViewHolder,会持有BaseAdapter主要会做一些回调。其实这些思想我觉得挺好,比如:抽取BaseActivity和BaseFragment的时候,使用这些思想还是挺好的。