1 Star 3 Fork 1

沉璧浮光/RVAdapter

Create your Gitee Account
Explore and code with more than 13.5 million developers,Free private repositories !:)
Sign up
This repository doesn't specify license. Please pay attention to the specific project description and its upstream code dependency when using it.
Clone or Download
contribute
Sync branch
沉璧浮光-cbfg5210 沉璧浮光 debug 2adc8fb 11 days ago
Cancel
Notice: Creating folder will generate an empty file .keep, because not support in Git
Loading...
README

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

Empty file

About

RecyclerView.Adapter 封装 expand collapse
Cancel

Releases (16)

All
11 days ago

Contributors

All

Activities

can not load any more
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Android
1
https://gitee.com/cbfg5210/RVAdapter.git
git@gitee.com:cbfg5210/RVAdapter.git
cbfg5210
RVAdapter
RVAdapter
master

Search