RecyclerView 添加单选多选功能

在哪看过一个帖子,不记得了,完事仿着思路写的,很简单

  1. 工具类
    CheckHelper 抽象基类
import android.view.View
import androidx.recyclerview.widget.RecyclerView

abstract class CheckHelper( recyclerView:RecyclerView){

//如果点击事件不是整个item的话,传入要点击的view的id
     fun bindViewHolder(viewHolder: RecyclerView.ViewHolder, redID:Int){
        bindViewHolder(viewHolder,viewHolder.itemView.findViewById<View>(redID))
    }
//默认点击事件是整个item
     fun bindViewHolder(viewHolder: RecyclerView.ViewHolder){
        bindViewHolder(viewHolder,viewHolder.itemView)
    }
    abstract fun bindViewHolder(viewHolder: RecyclerView.ViewHolder,clickView:View)

//用来处理选中状态改变后状况,比如你想修改文本内容
    var handleStateChange:((RecyclerView.ViewHolder,Boolean)->Unit)?=null

    fun stateChange(viewHolder: RecyclerView.ViewHolder,checked:Boolean){
        viewHolder.itemView.isSelected=checked
        handleStateChange?.invoke(viewHolder,checked)
    }

    abstract fun isCheckedPosition(position:Int):Boolean
}

单选
SingleCheckHelper 类

import android.view.View
import androidx.recyclerview.widget.RecyclerView

class SingleCheckHelper(val recyclerView: RecyclerView): CheckHelper(recyclerView){
    override fun isCheckedPosition(position: Int): Boolean {
        return position==checked
    }

    override fun bindViewHolder(viewHolder: RecyclerView.ViewHolder, clickView: View) {
        val position=viewHolder.adapterPosition
        clickView.setOnClickListener {
            val contain=isCheckedPosition(position)
            stateChange(viewHolder,!contain)
            if(contain){
                checked=-1
            }else{
                if(checked!=-1){
                    recyclerView.findViewHolderForAdapterPosition(checked)?.apply {
                        stateChange(this,false)
                    }
                }
                checked=position
            }

        }
        stateChange(viewHolder,isCheckedPosition(position))
    }
    var checked=-1
}

多选
MultiCheckHelper

import android.util.SparseIntArray
import android.view.View
import androidx.recyclerview.widget.RecyclerView

class MultiCheckHelper(val recyclerView: RecyclerView) : CheckHelper(recyclerView) {

    val checkedArrays = SparseIntArray()
    override fun bindViewHolder(viewHolder: RecyclerView.ViewHolder, clickView: View) {

        val position = viewHolder.adapterPosition
        clickView.setOnClickListener {
            val contain = isCheckedPosition(position)
            stateChange(viewHolder, !contain)
            if (contain) {
                checkedArrays.delete(position)
            } else {
                checkedArrays.put(position, 1)
            }
        }
        stateChange(viewHolder, isCheckedPosition(position))
    }

    override fun isCheckedPosition(position: Int): Boolean {
        if (checkedArrays.size() == 0) {
            return false
        }
        return checkedArrays.get(position) != 0
    }
}

单选多选保存的都是选中的position,所以和数据类型无关了。

代码中使用

var checkHelper:CheckHelper?=null

//单选实现
            checkHelper= SingleCheckHelper(rv_demo).apply {
                checked=0
                handleStateChange={viewHolder, checked ->
//这里演示下,选中以后修改textview显示的内容。
                    (viewHolder as BaseRvHolder).apply {
                        setText(R.id.tv_content,if(checked)"I was chosen!!!" else "content${viewHolder.adapterPosition}")
                    }
                }
            }


//多选,如果不需要特殊处理,就new个对象就完事了。
checkHelper=MultiCheckHelper(rv_demo)

然后bindView里使用helper类即可

                override fun onBindViewHolder(holder: BaseRvHolder, position: Int) {
                   holder.setText(R.id.tv_title,"title$position")
                           .setText(R.id.tv_content,"content$position")
              //加上下边代码即可
                    checkHelper?.bindViewHolder(holder)
//如果你想把点击事件设置到item里的某个控件上,那么加上第二个参数 控件id即可
                }

然后就是布局里你要修改文字颜色,背景图啥的,写好对应的状态文件即可,如下

android:textColor="@color/select_title_color"
android:background="@drawable/select_cb"

select_title_color.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/color_title_select" android:state_pressed="true" />
    <item android:color="@color/color_title_select" android:state_selected="true" />
    <item android:color="@color/color_title_normal" />
</selector>

select_cb.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/iv_leaf_1" android:state_pressed="true" />
    <item android:drawable="@drawable/iv_leaf_1" android:state_selected="true" />
    <item android:drawable="@drawable/iv_leaf_3" />
</selector>

获取选中的数据,都是position

单选就是这个变量 checked
多选是这个 checkedArrays

    原文作者:有点健忘
    原文地址: https://www.jianshu.com/p/2a5ce92c61ab
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞