前言
我们之前在使用ListView时,经常遇到含有CheckBox实现多选或者RaidoButton实现单选的问题,我们常使用的办法就是记着选择位置,当然在RecyclerView中原理是一样的,这里记录一下!
还有就是讨论一下,如果item中含有RadioGroup,而不是单选RadioButton,列表中check错乱的问题!
CheckBox多选和Radio单选
这两个原理一样,这里就以CheckBox多选为例,来说明一下!
首先我们用一个SparseBooleanArray
来保存选择的位置是否被勾选!
在Adapter中添加一个字段
private SparseBooleanArray mSelectedPositions = new SparseBooleanArray();
然后在RecyclerView点击事件中调用下边的方法,选中则将数组值置为true,默认为false。RecyclerView的点击事件,在这里就不再赘述了,应该算是比较基础的内容了!
public void setItemChecked(int position) {
//这里取反
mSelectedPositions.put(position, !mSelectedPositions.get(position));
notifyItemChanged(position);
}
最后,遍历SparseBooleanArray,得到整个选中的内容,当然在遍历的时候要先判断SparseBooleanArray中的值是否为true。
public ArrayList<String> getSelectedStringItem() {
ArrayList<String> selectList = new ArrayList<>();
for (int i = 0; i < stringList.size(); i++) {
if (mSelectedPositions.get(i)) {
selectList.add(stringList.get(i));
}
}
return selectList;
}
好了,item中含有checkbox的多选就先到这里了,radio的单选是一个道理。
RadioGroup中选择错乱的问题
如果我们的item中含有RadioGroup,而且我们在删除或者添加item,或者条目超过一个屏幕来回上下滑动,刷新UI的时候,就会发现RadioGroup中check错乱!
在StackOverFlower中有一个回答,可以参考一下:
Select only one radiobutton in a recyclerview
下面说一下我的方案,原理都是一样的,这里随便一个实体类为例,说明一下:
在我们的adapter中onBindViewHolder
方法中:
holder.a.setText(entity.getA());
holder.radioGroup.setOnCheckedChangeListener(null);//重点,取消监听
String b=entity.getB();
if (!TextUtils.isEmpty(b)){
initRadio(holder.radioGroup, b);
}else {
holder.radioGroup.clearCheck();//这里如果没有值,则清空
}
holder.radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
RadioButton button = (RadioButton) group.findViewById(checkedId);
String b= button.getText().toString();
entity.setB(b);
}
});
这里要特别说明一下,在初始化RadioGroup之前,我们要先取消RadioGroup的监听,因为我们在初始化的时候,不管是调用setCheck(true)
还是check(R.id.radioButton)
来初始化选择,都会被checkChangeListener监听到,从而使没有数据的item也获得数据,所以在初始化选中之前,要去掉监听!
还有就是,如果该位置的值为空,则不要初始化,要调用clearCheck()方法来清空,这样就避免了来回滑动,item复用的原因导致的check错乱!
上边就是该方案比较核心的问题了!
其他
我在查阅一些资料的时候,发现有很多人在使RadioGroup选择某一项时,调用check(R.id.radioButton)时,发现OnCheckChangedListerner()方法会调用两遍(有的竟然三遍),这里我还没有具体的去验证。
为了避免这一问题呢,我们在设置选中的时候,可以这样写:
((RadioButton)radioGroup.findViewById(R.id.radio)).setChecked(true);
可以避免这个问题!