RecyclerView 添加单选多选功能
2019-03-19 本文已影响4人
有点健忘
在哪看过一个帖子,不记得了,完事仿着思路写的,很简单
- 工具类
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