1 问题
Recycleview的Item含有CheckBox,已经对部分Item项的进行CheckBox选中,在上下滑动过程中,CheckBox状态会出现错乱现象或消失问题。
2 不合理的解决方法(不正确方法)
查找很多资料,大部分都是建议使用SparseBooleanArray(用于跟踪记录哪些位置被选中)这样方式去处理,但是它并不能解决Recycleview滑动时已选中CheckBox出现错乱或变成未选中的问题。
/** 适配器关键代码DataAdapter */
class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private List<TeaTestResult> list;
private Context mContext;
private SparseBooleanArray selectedPositions; // 用于跟踪哪些位置被选中
public DataAdapter(BaseActivity mContext, List<TeaTestResult> list) {
this.mContext = mContext;
this.list = list;
this.selectedPositions = new SparseBooleanArray(); // 初始化SparseBooleanArray
}
@Override
public void onBindViewHolder(ViewHolder holder, final int i) {
TeaTestResult testResult = list.get(i);
// 设置复选框的状态
boolean isChecked = selectedPositions.get(i, false);
holder.checkbox.setChecked(isChecked);
holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
selectedPositions.put(i, b); // 更新SparseBooleanArray中的状态
testResult.setSelect(b); // 更新数据模型的状态
}
});
}
3 正确解决方法
经过一系列调试,最终发现CheckBox的onCheckedChanged方法在Recycleview的item销毁时会再次调用一次。因为Recycleview上下滑动过程中,Item项销毁后的数据要和Adapter数据源一致。如果单纯改变item,那么销毁时CheckBox就会再次调用onCheckedChanged。该如何解决这个问题呢?
我的方法是:把CheckBox放进容器里,让容器来关联CheckBox的状态,CheckBox啥也不干
3.1 容器控件代码
容器代码:
public class LinLinearLayout extends LinearLayout {
... 省略构造方法
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return true; // 关键在这里,对事件进行拦截
}
}
3.2 Item项布局CheckBox部分
<com.xx.LinLinearLayout
android:id="@+id/llCheck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="13dp">
<CheckBox
android:id="@+id/checkbox"
android:layout_width="@dimen/width_30"
android:layout_height="@dimen/width_30"
android:background="@drawable/ck_select"
android:button="@null" />
</com.xx.LinLinearLayout>
3.3 适配器Adapter 核心代码
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
... 省略其他不相干代码
@Override
public void onBindViewHolder(ViewHolder holder, final int i) {
TeaTestResult testResult = list.get(i);
// 第一步
holder.checkbox.setChecked(testResult.isSelect());
//llCheck是容器控件
holder.llCheck.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 第二步
if (holder.checkbox.isChecked()) {
holder.checkbox.setChecked(false);
testResult.setSelect(false);
} else {
holder.checkbox.setChecked(true);
testResult.setSelect(true);
}
}
});
}
}
看到这里了,是否能解决您的问题呢?
既然都到这里了,是不是少了一键三连系列动作呢~~~