博客
关于我
关于在MVVM框架中BaseRecyclerViewAdapter的封装
阅读量:766 次
发布时间:2019-03-24

本文共 5355 字,大约阅读时间需要 17 分钟。

关于在MVVM框架中BaseRecyclerViewAdapter的封装

在Android Studio 4.0及之后版本中,黄油刀(butter knife)因不适配AndroidX库而逐渐退出舞台,官方也发布公告称将不再继续支持。这意味着开发者需要重新考虑数据绑定相关的布局和Adapter封装方式。在此背景下,建议使用官方提供的ViewDataBinding来进行RecyclerView Adapter的封装和优化。本文将介绍如何将现有的YellowButterknife代码重新转型为ViewDataBinding的应用,并在此基础上对RecyclerView Adapter进行封装和拓展。

作为一名开发者,我决定重新对RecyclerView的Adapter进行封箱与优化,解决以下问题:

  • 去除YellowButterKnife并减少 findViewById 调用:希望实现更强大的View绑定功能,避免依赖于静态查找控件。
  • 区分普通列表与头布局模式:通过新增单独的头布局实现多样化列表展示。
  • 封装点击事件和长按事件:为列表项添加交互功能,确保头布局模式下的特殊性处理。
  • 统一ViewHolder封装:提供通用的ViewHolder实现,方便扩展和使用。
  • 封装后的代码效果

    通过封装后代码的简洁性,可以看出这种方式对开发者来说更加高效和便捷。例如,常规的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的实现

    BaseRecyclerViewAdapter 是我们的核心基类,主要功能包括:

  • 去除YellowButterKnife:通过 ViewDataBinding 默认实现了View的绑定功能,无需手动查找控件。
  • 支持头布局模式:通过动态判断 itemViewType,实现单独的头布局展示。
  • 提供多种交互选项:实现点击事件、长按事件等,符合用户对列表交互的需求。
  • 前后兼容:兼顾旧版和新版项目,确保在多种场景下都能使用。
  • BaseViewHolder的实现

    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) // ... 其他方法}

    BaseViewHolder的实现

    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/

    你可能感兴趣的文章
    mysql 网络目录_联机目录数据库
    查看>>
    MySQL 聚簇索引&&二级索引&&辅助索引
    查看>>
    Mysql 脏页 脏读 脏数据
    查看>>
    mysql 自增id和UUID做主键性能分析,及最优方案
    查看>>
    Mysql 自定义函数
    查看>>
    mysql 行转列 列转行
    查看>>
    Mysql 表分区
    查看>>
    mysql 表的操作
    查看>>
    mysql 视图,视图更新删除
    查看>>
    MySQL 触发器
    查看>>
    mysql 让所有IP访问数据库
    查看>>
    mysql 记录的增删改查
    查看>>
    MySQL 设置数据库的隔离级别
    查看>>
    MySQL 证明为什么用limit时,offset很大会影响性能
    查看>>
    Mysql 语句操作索引SQL语句
    查看>>
    MySQL 误操作后数据恢复(update,delete忘加where条件)
    查看>>
    MySQL 调优/优化的 101 个建议!
    查看>>
    mysql 转义字符用法_MySql 转义字符的使用说明
    查看>>
    mysql 输入密码秒退
    查看>>
    mysql 递归查找父节点_MySQL递归查询树状表的子节点、父节点具体实现
    查看>>