本文共 5355 字,大约阅读时间需要 17 分钟。
关于在MVVM框架中BaseRecyclerViewAdapter的封装
在Android Studio 4.0及之后版本中,黄油刀(butter knife)因不适配AndroidX库而逐渐退出舞台,官方也发布公告称将不再继续支持。这意味着开发者需要重新考虑数据绑定相关的布局和Adapter封装方式。在此背景下,建议使用官方提供的ViewDataBinding来进行RecyclerView Adapter的封装和优化。本文将介绍如何将现有的YellowButterknife代码重新转型为ViewDataBinding的应用,并在此基础上对RecyclerView Adapter进行封装和拓展。
作为一名开发者,我决定重新对RecyclerView的Adapter进行封箱与优化,解决以下问题:
通过封装后代码的简洁性,可以看出这种方式对开发者来说更加高效和便捷。例如,常规的Adapter类可以像下面这样的代码展示:
class JokeAdapter(context: Context) : BaseRecyclerViewAdapter{ override fun getLayoutId(): Int { return R.layout.joke_item } override fun onBindHolder( holder: BaseViewHolder , position: Int ) { holder.getBinding().setItem(mList.get(position)) }}
从代码中可以看出,开发者只需要继承BaseRecyclerViewAdapter,并提供相应的数据类型和布局即可,实现起来更加简洁高效。
BaseRecyclerViewAdapter 是我们的核心基类,主要功能包括:
ViewHolder 的封装是 BaseRecyclerViewAdapter 的重要组成部分,它负责管理和操作每个RecyclerView项的绑定和刷新。BaseViewHolder 的实现如下:
class BaseViewHolder: RecyclerView.ViewHolder { private val binding: T private val headerBinding: ViewDataBinding? = null private val isHeaderViewHolder: Boolean = false constructor(binding: T) : super(binding.root) { this.binding = binding } constructor(headerBinding: ViewDataBinding, isHeaderViewHolder: Boolean) : super(headerBinding.root) { this.isHeaderViewHolder = isHeaderViewHolder this.headerBinding = headerBinding this.binding = null } fun getBinding(): T = binding fun getHeaderBinding(): ViewDataBinding? = headerBinding}
交互功能是使用BaseRecyclerViewAdapter 的重要体现,通过在onBindViewHolder方法中添加点击事件和长按事件处理,用户可以在RecyclerView列表中实现单项交互。
以下是完整的代码示例,展示了BaseRecyclerViewAdapter以及其相关辅助类的实现:
package com.jcloudsoft.demo.baseimport android.content.Contextimport android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupimport androidx.annotation.LayoutResimport androidx.databind.BinaryOperatorimport androidx.databinding.DataBindingUtilimport androidx.databinding.ViewDataBindingimport androidx.recyclerview.widget.RecyclerViewimport java.util.*abstract class BaseRecyclerViewAdapter: RecyclerView.Adapter >, SimpleItemTouchHelperCallback.ItemTouchHelperAdapter { protected var mContext: Context protected var mList: List = ArrayList() protected var headerView: View? = null private var headerViewId: Int = -1 companion object { const val TYPE_HEAD = 1 const val TYPE_NORMAL = 0 } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder { if (viewType == TYPE_HEAD && headerViewId != -1) { val binding = DataBindingUtil.inflate( LayoutInflater.from(parent.context), headerViewId, parent, false ) return BaseViewHolder(binding, true) } val binding = DataBindingUtil.inflate( LayoutInflater.from(parent.context), getLayoutId(), parent, false ) return BaseViewHolder(binding) } override fun onBindViewHolder(holder: BaseViewHolder , position: Int) { if (headerView == null) { if (position == 0) { return } } if (getItemViewType(position) == TYPE_HEAD) { onBindHeaderHolder(holder, getRealPosition(holder)) return } holder.getBinding().root.setOnClickListener { v -> if (mOnItemClickListener != null) { mOnItemClickListener.onItemClick(v, getRealPosition(holder)) } } holder.getBinding().root.setLongClickable { v -> if (mOnItemLongClickListener != null) { mOnItemLongClickListener.onItemLongClick(v, getRealPosition(holder)) true } false } onBindHolder(holder, getRealPosition(holder)) } protected abstract val mList: List protected abstract val layoutId: Int @LayoutRes get protected abstract fun onBindHolder(holder: BaseViewHolder , position: Int) protected abstract fun onBindHeaderHolder(holder: BaseViewHolder , position: Int) // ... 其他方法}
package com.jcloudsoft.demo.baseimport android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupimport androidx.databinding.ViewDataBindingimport androidx.recyclerview.widget.RecyclerViewclass BaseViewHolder: RecyclerView.ViewHolder { private val binding: T private val headerBinding: ViewDataBinding? = null private val isHeaderViewHolder: Boolean = false constructor(binding: T) : super(binding.root) { this.binding = binding } constructor(headerBinding: ViewDataBinding, isHeaderViewHolder: Boolean) : super(headerBinding.root) { this.isHeaderViewHolder = isHeaderViewHolder this.headerBinding = headerBinding this.binding = null } fun getBinding(): T = binding fun getHeaderBinding(): ViewDataBinding? = headerBinding // ... 其他属性和方法}
通过上述封装,我们可以更灵活地处理RecyclerView列表,支持多种布局模式和交互功能,同时提高代码的可维护性和可读性。
转载地址:http://saukk.baihongyu.com/