RecyclerView中含有CheckBox和RadioGoup全解

前言

我们之前在使用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.major.setText(checkReferMajorEntity.getMajor());
holder.radioGroup.setOnCheckedChangeListener(null);//重点,取消监听
String progress=checkReferMajorEntity.getProgress();
if (!TextUtils.isEmpty(progress)){
    initProgressRadio(holder.radioGroup, progress);
}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 progress = button.getText().toString();
        checkReferMajorEntity.setProgress(progress);
    }
});

这里要特别说明一下,在初始化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);

可以避免这个问题!

相关文章
相关标签/搜索