今天在使用
RecycleView
和checkBox
做列表时发现一个很有趣的问题,当我选中某一个checkBox
后,RecycleView
向下滑动时发现其他的checkBox
也被选中了,bug
图如下:
发生这个问题的原因在于
RecycleView
的复用机制,当我们向下滑动时RecycleView
会复用离开屏幕的Holder
从而来提高效率,而Holder
会保存checkBox
的选中状态,所以出现了上图这个bug。
解决方法:
使用一个集合来标记所有
checkBox
的位置和状态,点击checkBox
时将位置和状态存入集合。当我们向下滑动时,新的item
都会去集合中获取判断自己的选中状态,因为没有在集合存过所以返回false
,因此新的item
都是未选中的。而当我们向上滑动时,每个item
也会去集合中获取判断自己的选中状态。如果之前我们选中过则会在集合中有记录,我们传入下标来获取item
的状态。而SparseBooleanArray
作为这个集合则是最好的选择,它以int
为key
,boolean
作为value
,如果不存在则返回false
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
List<Integer> mList;
//保存状态的集合,SparseBooleanArray是以int为key,boolean作为value
private SparseBooleanArray mCheckStates = new SparseBooleanArray();
public MyAdapter(List<Integer> mList) {
this.mList = mList;
}
@NonNull
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
MyViewHolder holder = new MyViewHolder(View.inflate(Main4Activity.this, R.layout.item_rv, null));
return holder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, final int i) {
//以下标给每个checkBox加上唯一标识
myViewHolder.checkBox.setTag(i)