前言
之前一直使用kotlin,kotlin的插件挺好用的,现在建议使用ViewBinding,索性将获取布局方式修改为ViewBinding,之前了解Jetpack系列感觉Lifecycle挺好用的,将Android中组件化提高了一个档次,所以有了以下封装,好了废话不多说直接上代码.
1.先上接口,此接口主要将Adapter中需要实现的功能代理出去
interface AdapterImpl<B: Any, VB: ViewBinding> {
/// 初始化viewBinding
fun initViewHolder(parent: ViewGroup, viewType: Int): ViewBindingRvCurrencyHolder<VB>
/// 实际处理
fun onBindViewHolder(holder: ViewBindingRvCurrencyHolder<VB>, position: Int, binding: VB, bean: B)
}
// 通用ViewHolder
open class ViewBindingRvCurrencyHolder<VB : ViewBinding>(val binding: VB): RecyclerView.ViewHolder(binding.root) {
// 设置item点击事件
fun setItemOnClickListener(click: View.OnClickListener) {
binding.root.setOnClickListener(click)
}
// 设置item点击事件
fun setItemOnClickListener(click: (View) -> Unit) {
binding.root.setOnClickListener(click)
}
}
2. Adapter封装
abstract class RvCurrencyAdapter<T : Any, VH : RecyclerView.ViewHolder>(private val context: Context) :
RecyclerView.Adapter<VH>() {
protected val inflater: LayoutInflater = LayoutInflater.from(context)
// 数据源
open var dataList: MutableList<T> = mutableListOf()
set(value) {
field = value
notifyItemRangeChanged(0, value.size)
}
// 添加一条数据刷新
fun addItemData(data: T) {
dataList.add(data)
notifyDataSetChanged()
}
// 向末尾添加数据
fun addItemDataAll(data: List<T>) {
dataList.addAll(data)
notifyDataSetChanged()
}
abstract override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH
override fun onBindViewHolder(holder: VH, position: Int) {
onBindViewHolder(holder, holder.adapterPosition, dataList[holder.adapterPosition])
}
override fun getItemCount(): Int = dataList.size
abstract fun onBindViewHolder(
holder: VH,
position: Int,
bean: T
)
/// 创建ViewBindingRvCurrencyHolder对象
inline fun <reified T : ViewBinding> bindingViewHolderNew(parent: ViewGroup): ViewBindingRvCurrencyHolder<T> {
val method = T::class.java.getMethod("inflate", LayoutInflater::class.java, ViewGroup::class.java, Boolean::class.java)
val binding = method.invoke(null, LayoutInflater.from(parent.context), parent, false) as T
return ViewBindingRvCurrencyHolder(binding)
}
}
/**
* ViewBinding与Adapter结合使用
*/
abstract class ViewBindingRvCurrencyAdapter<T : Any, VB : ViewBinding>(val context: Context) :
RvCurrencyAdapter<T, ViewBindingRvCurrencyHolder<VB>>(context) {
override fun onBindViewHolder(holder:ViewBindingRvCurrencyHolder<VB>, position: Int, bean: T) {
onBindViewHolder(holder, position, holder.binding, bean)
}
abstract fun onBindViewHolder(holder: ViewBindingRvCurrencyHolder<VB>, position: Int, binding: VB, bean: T)
}
/**
* 单布局, 将rv功能封装对外提供
*/
class SingleLayoutBaseNewAdapter<B: Any, VB: ViewBinding>(context: Context, private val impl: AdapterImpl<B, VB>): ViewBindingRvCurrencyAdapter<B, VB>(context) {
override fun onCreateViewHolder(parent: ViewGroup,viewType: Int): ViewBindingRvCurrencyHolder<VB> {
return impl.initViewHolder(parent, viewType)
}
override fun onBindViewHolder(holder: ViewBindingRvCurrencyHolder<VB>, position: Int, binding: VB, bean: B) {
impl.onBindViewHolder(holder, position, binding, bean)
}
}
3.RecyclerView的封装
/**
* 简化RecyclerView的使用
* B: 数据集
* VB: ViewBinding绑定布局
* 使用:
* 1.继承BaseRecyclerView
* 2.在activity中使用lifecycle.addObserver(rvId)监听控件
*/
abstract class BaseRecyclerView<B: Any, VB: ViewBinding>: RecyclerView, LifecycleObserver {
// 定义适配器
private lateinit var baseAdapter: SingleLayoutBaseNewAdapter<B, VB>
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
}
// 返回新adapter
fun getBaseAdapter(): SingleLayoutBaseNewAdapter<B, VB> = baseAdapter
/// 初始化viewBinding
protected abstract fun initViewHolder(parent: ViewGroup, viewType: Int): ViewBindingRvCurrencyHolder<VB>
/// 实际处理
protected abstract fun onBindViewHolder(holder: ViewBindingRvCurrencyHolder<VB>, position: Int, binding: VB, bean: B)
/// rv布局方式
protected abstract fun layoutManager(): LayoutManager
// 添加一条数据刷新
fun addItemData(data: B) {
getBaseAdapter().addItemData(data)
}
// 向末尾添加数据
fun addItemDataAll(data: List<B>) {
getBaseAdapter().addItemDataAll(data)
}
/// 初始化
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
private fun onCreate() {
baseAdapter = SingleLayoutBaseNewAdapter(context, object: AdapterImpl<B, VB> {
override fun initViewHolder(parent: ViewGroup, viewType: Int): ViewBindingRvCurrencyHolder<VB> {
return this@BaseRecyclerView.initViewHolder(parent, viewType)
}
override fun onBindViewHolder(holder: ViewBindingRvCurrencyHolder<VB>, position: Int, binding: VB, bean: B) {
this@BaseRecyclerView.onBindViewHolder(holder, position, binding, bean)
}
})
this.adapter = baseAdapter
this.layoutManager = layoutManager()
}
}
4. 使用
class MyRecyclerView: BaseRecyclerView<DemoHttpBean, RvDemoHttpBinding> {
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
}
override fun initViewHolder(
parent: ViewGroup,
viewType: Int
): ViewBindingRvCurrencyHolder<RvDemoHttpBinding> = getBaseAdapter().bindingViewHolderNew(parent)
override fun onBindViewHolder(
holder: ViewBindingRvCurrencyHolder<RvDemoHttpBinding>,
position: Int,
binding: RvDemoHttpBinding,
bean: DemoHttpBean
) {
holder.binding.tvTitle.text = bean.title
holder.binding.tvContent.text = bean.content
Log.e("fyc", ">>>>>>>>>>>>>> onBindViewHolder <<<<<<<<<<<<<<<<<<<<<")
holder.setItemOnClickListener {
Toast.makeText(context, "item点击事件触发", Toast.LENGTH_LONG).show()
}
}
override fun layoutManager(): LayoutManager = LinearLayoutManager(context)
}
class TestRvOneAc : AppCompatActivity() {
private val binding: AcTestRvOneBinding by inflate()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycle.addObserver(binding.rvTestData)
}
override fun onDestroy() {
super.onDestroy()
}
}
总结
整体使用比较简单,不用担心性能问题。