Skip to content

cbfg5210/RVAdapter

Repository files navigation

RVAdapter

本库基于 https://github.com/cbfg5210/BRecyclerAdapter 进行了重新封装,对原有的代码逻辑缺陷进行了修复,并改善了使用方式。比如:

  • 【旧】使用了 List 来保存选中项,容易导致重复保存相同 item
    【新】使用 Set 来保存,确保无重复 item
  • 【旧】对数据操作后需要手动调用刷新
    【新】数据操作后自动刷新
  • 【旧】返回的列表数据是 MutableList,容易被篡改
    【新】返回 List 类型,操作闭环
  • 【旧】没有提供选中 item 的 api,需要获取选中列表自行添加/移除选中项,不方便并且容易出错
    【新】提供了系列 api
  • 【旧】BRecyclerAdapter 中的代码臃肿,可以独立出来的没有独立出来
    【新】该独立能独立的代码独立出来
  • 【旧】状态页支持不完全,不能动态修改内容,不能设置点击事件
    【新】完全支持自定义状态页及修改其内容以及设置点击事件

读者可以通过对比二者源码直接体会其中优劣:

接下来介绍一下新库的使用方法:

引入依赖

Step 1. Add the JitPack repository to your build file

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

Step 2. Add the dependency

dependencies {
    implementation 'com.gitee.cbfg5210:RVAdapter:$version'
}

使用

Step 1. 继承 RVHolderFactory 并实现抽象方法 createViewHolder

class SimpleVHFactory : RVHolderFactory() {
    override fun createViewHolder(
        parent: ViewGroup?,
        viewType: Int,
        item: Any
    ): RVHolder<out Any> {
        return PersonVH(inflate(R.layout.item_person, parent))
    }

    private class PersonVH(itemView: View) : RVHolder<Person>(itemView) {
        private val ivAvatar = itemView.ivAvatar
        private val tvName = itemView.tvName

        @SuppressLint("SetTextI18n")
        override fun setContent(item: Person, isSelected: Boolean, payload: Any?) {
            ivAvatar.setImageResource(item.avatar)
            tvName.text = "${item.name} - $adapterPosition"
        }

        override fun setListeners(
            itemClickListener: View.OnClickListener?,
            itemLongClickListener: View.OnLongClickListener?
        ) {
            /**
             * 这里除了 item 设置点击/长按事件外,也给头像设置点击事件
             */
            super.setListeners(itemClickListener, itemLongClickListener)
            ivAvatar.setOnClickListener(itemClickListener)
        }
    }
}

Step 2. 页面使用

val adapter = RVAdapter<Person>(view.context, SimpleVHFactory())
        .bindRecyclerView(rvTest)
        .setItems(
            DataHelper.getPeople(),
            clearSelections = false,
            needNotify = false
        )
        .setItemClickListener { v, item, position ->
            /**
             * 点击头像
             */
            if (v.id == R.id.ivAvatar) {
                val tip = "click avatar ${item.name} - $position"
                Toast.makeText(view.context, tip, Toast.LENGTH_SHORT).show()
            }
            /**
             * 点击 item
             */
            val tip = "click item ${item.name} - $position"
            Toast.makeText(view.context, tip, Toast.LENGTH_SHORT).show()
        }
        .setItemLongClickListener { _, item, position ->
            val tip = "long click ${item.name} - $position"
            Toast.makeText(view.context, tip, Toast.LENGTH_SHORT).show()
        }

直达 DEMO

API 一览

/**
 * 给 RecyclerView 设置 adapter
 */
fun bindRecyclerView(rv: RecyclerView): RVAdapter<T>

/**
 * 设置点击事件
 */
fun setItemClickListener(listener: (view: View, item: T, position: Int) -> Unit): RVAdapter<T>

/**
 * 设置长按事件
 */
fun setItemLongClickListener(listener: (view: View, item: T, position: Int) -> Unit): RVAdapter<T>

/**
 * 设置状态页点击事件
 */
fun setStateClickListener(listener: (view: View, item: Any, position: Int) -> Unit): RVAdapter<T>

/**
 * 设置生命周期事件处理
 */
fun setLifecycleHandler(lifecycleHandler: RVLifecycleHandler): RVAdapter<T>

/**
 * 获取 items
 */
fun getItems(): List<T>

/**
 * 获取选中项
 */
fun getSelections(): Set<T>

/**
 * 是否可选
 */
fun isSelectable(): Boolean

/**
 * 指定数据类型是否可选
 */
fun isSelectable(clazz: Class<*>)

/**
 * 设置(不)可选,设为 false 的话表示所有数据类型都不可选,相当于总开关
 */
fun setSelectable(
        selectable: Boolean,
        clearSelections: Boolean = true,
        needNotify: Boolean = true
    ): RVAdapter<T>

/**
 * 设置指定类型数据是否可选
 */
fun setSelectable(
        clazz: Class<*>,
        strategy: SelectStrategy,
        clearItsSelections: Boolean = true,
        needNotify: Boolean = true
    ): RVAdapter<T>

/**
 * 设置数据
 * @param clearSelections true:清空选中项
 * @param needNotify true:刷新
 */
fun setItems(
        items: List<T>?,
        clearSelections: Boolean = true,
        needNotify: Boolean = true
    ): RVAdapter<T>

/**
 * 添加一项数据
 */
fun fun add(item: T)

/**
 * 向指定位置插入一项数据,注意 index 不要超出范围
 */
fun fun add(index: Int, item: T)

/**
 * 添加多项数据
 */
fun fun add(list: List<T>)

/**
 * 向指定位置插入多项数据,注意 index 不要超出范围
 */
fun fun add(index: Int, list: List<T>)

/**
 * 移除一项数据
 */
fun fun remove(item: T)

/**
 * 移除指定位置的一项数据,注意 index 不要超出范围
 */
fun fun removeAt(index: Int)

/**
 * 数据多项数据
 */
fun fun remove(list: Collection<T>)

/**
 * 移除指定范围的数据,注意 fromIndex、toIndex 不要超出范围
 */
fun fun removeRange(fromIndex: Int, toIndex: Int)

/**
 * 清空数据
 * @param alsoSelections true:清空选中项
 * @param needNotify true:刷新
 */
fun fun clear(alsoSelections: Boolean = true, needNotify: Boolean = true)

/**
 * 选中 item
 * 该类型允许选择才可以选中,否则抛出异常
 */
fun fun select(item: T)

/**
 * 选中指定位置 item,注意 index 不要超出范围
 */
fun fun selectAt(index: Int)

/**
 * 选中多项 item
 * 该类型允许选择才可以选中,否则抛出异常
 * 该类型如果是单选的话,选中多项会抛出异常
 *  @param strictCheck true:严格检查数据类型是否单选,如果单选并且选中多项则抛出异常
 */
fun fun select(list: Collection<T>, strictCheck: Boolean = false)

/**
 * 选中指定范围的多个 item,注意 fromIndex、toIndex 不要超出范围
 * 该类型允许选择才可以选中,否则抛出异常
 * 该类型如果是单选的话,选中多项会抛出异常
 *  @param strictCheck true:严格检查数据类型是否单选,如果单选并且选中多项则抛出异常
 */
fun fun selectRange(fromIndex: Int, toIndex: Int, strictCheck: Boolean = false)

/**
 * 选中指定类型 item 所有数据,类型是单选的话只会选中一项
 */
fun fun select(clazz: Class<*>)

/**
 * 选中所有 item
 * 该类型允许选择才可以选中,否则抛出异常
 * 该类型如果是单选的话,选中多项会抛出异常
 *  @param strictCheck true:严格检查数据类型是否单选,如果单选并且选中多项则抛出异常
 */
fun fun selectAll(strictCheck: Boolean = false)

/**
 * 取消选中指定位置 item,注意 index 不要超出范围
 */
fun fun deselectAt(index: Int)

/**
 * 取消选中 item
 */
fun fun deselect(item: T)

/**
 * 取消选中多个 item
 */
fun fun deselect(list: Collection<T>)

/**
 * 取消选中指定类型 item 所有数据
 * @param needNotify true:刷新
 */
fun fun deselect(clazz: Class<*>, needNotify: Boolean = true)

/**
 * 全部不选中
 */
fun fun deselectAll()

/**
 * 显示状态页,调用这个方法前要设置 [stateHolderFactory],否则抛出异常
 * @param isEmptyState true:空白页
 */
fun fun showStatePage(state: Any, isEmptyState: Boolean = false)

/**
 * 获取数据数量,如果有状态页的话,这个可能不准确
 */
fun fun getItemCount(): Int

/**
 * 获取实际的数据数量
 */
fun fun getRealItemCount(): Int

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages