美文网首页Android开发
RecyclerView 添加单选多选功能

RecyclerView 添加单选多选功能

作者: 有点健忘 | 来源:发表于2019-03-19 18:15 被阅读4次

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

    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

    相关文章

      网友评论

        本文标题:RecyclerView 添加单选多选功能

        本文链接:https://www.haomeiwen.com/subject/tnunmqtx.html