在哪看过一个帖子,不记得了,完事仿着思路写的,很简单
- 工具类
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
记录下java代码
有的工程不是kt写的,还是弄套java的,方便复制
基类
import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
/**RecyclerView实现单选多选的抽象类*/
public abstract class CheckHelper {
RecyclerView recyclerView;
public CheckHelper(RecyclerView recyclerView) {
this.recyclerView=recyclerView;
}
//如果点击事件不是整个item的话,传入要点击的view的id
public void bindViewHolder(RecyclerView.ViewHolder viewHolder, int redID) {
bindViewHolder(viewHolder, viewHolder.itemView.findViewById(redID));
}
//默认点击事件是整个item
public void bindViewHolder(RecyclerView.ViewHolder viewHolder) {
bindViewHolder(viewHolder, viewHolder.itemView);
}
abstract void bindViewHolder(RecyclerView.ViewHolder viewHolder, View clickView);
//用来处理选中状态改变后状况,比如你想修改文本内容
public void stateChange(RecyclerView.ViewHolder viewHolder, Boolean checked) {
viewHolder.itemView.setSelected(checked);
handleChange(viewHolder, checked);
}
abstract boolean isCheckedPosition(int position);
public interface HandleStateChange {
void stateChange(RecyclerView.ViewHolder viewHolder, boolean checked);
void clickWhich(int position);
}
public HandleStateChange handleStateChange;
protected void handleChange(RecyclerView.ViewHolder viewHolder, boolean checked){
if (handleStateChange != null) {
handleStateChange.stateChange(viewHolder, checked);
}
}
protected void clickWhich(int position){
if (handleStateChange != null) {
handleStateChange.clickWhich(position);
}
}
}
单选实现,这里点击已选中的不会取消选中
import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
public class SingleCheckHelper extends CheckHelper {
private int checked = -1;
public SingleCheckHelper(RecyclerView recyclerView) {
super(recyclerView);
}
public SingleCheckHelper(RecyclerView recyclerView, int checked) {
super(recyclerView);
this.checked = checked;
}
public void setChecked(int checked) {
this.checked = checked;
}
@Override
void bindViewHolder(final RecyclerView.ViewHolder viewHolder, View clickView) {
final int position = viewHolder.getAdapterPosition();
clickView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean contain = isCheckedPosition(position);
if (contain) {
handleChange(viewHolder, true);
} else {
if (checked != -1) {
RecyclerView.ViewHolder holder = recyclerView.findViewHolderForAdapterPosition(checked);
if (holder != null) {
stateChange(holder, false);
}
}
checked = position;
stateChange(viewHolder, true);
}
clickWhich(position);
}
});
stateChange(viewHolder, isCheckedPosition(position));
}
@Override
boolean isCheckedPosition(int position) {
return position == checked;
}
}
多选
import android.util.SparseIntArray;
import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
public class MultiCheckHelper extends CheckHelper {
public MultiCheckHelper(RecyclerView recyclerView) {
super(recyclerView);
}
@Override
void bindViewHolder(final RecyclerView.ViewHolder viewHolder, View clickView) {
final int position = viewHolder.getAdapterPosition();
clickView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean contain = isCheckedPosition(position);
if (contain) {
checkedArrays.delete(position);
} else {
checkedArrays.put(position, 1);
}
stateChange(viewHolder, !contain);
}
});
stateChange(viewHolder, isCheckedPosition(position));
}
private SparseIntArray checkedArrays =new SparseIntArray();
public SparseIntArray getCheckedArrays() {
return checkedArrays;
}
public void setCheckedArrays(SparseIntArray checkedArrays) {
this.checkedArrays = checkedArrays;
}
@Override
boolean isCheckedPosition(int position) {
if (checkedArrays.size() == 0) {
return false;
}
return checkedArrays.get(position) != 0;
}
}