RecyclerView中使用CheckBox勾选混乱问题解决以及单选功能的实现

一.RecyclerView + CheckBox勾选混乱问题解决

RecyclerView中使用CheckBox时因为RecyclerView布局会重用,所以在勾选时出现勾选混乱。如图

勾选 0号位和2号位 21 23也被勾选了。

此时适配器中的代码

@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
    holder.mTextView.setText(mList.get(position));
}
想要解决勾选混乱问题,可以使用集合添加被勾选的CheckBox位置,然后集合中有的位置则设置为被勾选,没有的位置就设置不被勾选

效果如下:勾选 0 1 2 位置,并未出现勾选混乱

此时的代码

private Map<Integer, Boolean> map = new HashMap<>();

@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
    holder.mTextView.setText(mList.get(position));
    holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked == true) {
                map.put(position, true);
            } else {
                map.remove(position);
            }
        }
    });
    if (map != null && map.containsKey(position)) {
        holder.mCheckBox.setChecked(true);
    } else {
        holder.mCheckBox.setChecked(false);
    }
}
二.ReyclerView+CheckBox实现单选功能

方法:在每次设置CheckBox为true时,都将存有勾选的CheckBox的位置的集合清空,然后在将当前CheckBox加入进去,在通知适配器更新。

效果如下:

错误示例:

private Map<Integer, Boolean> map = new HashMap<>();

@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
    holder.mTextView.setText(mList.get(position));
    holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked == true) {
                map.clear();
                map.put(position, true);
            } else {
                map.remove(position);
            }
            notifyDataSetChanged();
        }
    });
    if (map != null && map.containsKey(position)) {
        holder.mCheckBox.setChecked(true);
    } else {
        holder.mCheckBox.setChecked(false);
    }
}
异常:java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling

提示说:不能在RecyclerView计算layout或者滑动的时候使用 notifyDataSetChanged() 方法
解决问题:添加判断条件,不在RecycerView计算layout或滑动的时候 通知适配器更新
private boolean onBind;

@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
    holder.mTextView.setText(mList.get(position));
    holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked == true) {
                map.clear();
                map.put(position, true);
            } else {
                map.remove(position);
            }
            if (!onBind) {
                notifyDataSetChanged();
            }
        }
    });
    onBind = true;
    if (map != null && map.containsKey(position)) {
        holder.mCheckBox.setChecked(true);
    } else {
        holder.mCheckBox.setChecked(false);
    }
    onBind = false;
}
三.获取CheckBox勾选的位置

完整的适配器代码:

public class CheckBoxAdapter extends RecyclerView.Adapter<CheckBoxAdapter.ViewHolder> {

    private List<String> mList;
    private Context mContext;

    private Map<Integer, Boolean> map = new HashMap<>();
    private boolean onBind;
    private int checkedPosition = -1;

    public CheckBoxAdapter(Context context, List<String> list) {
        this.mContext = context;
        this.mList = list;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.item_rcy_checkbox, parent, false);
        return new ViewHolder(view);
    }

    //得到当前选中的位置
    public int getCheckedPosition() {
        return checkedPosition;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        holder.mTextView.setText(mList.get(position));
        holder.mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked == true) {
                    map.clear();
                    map.put(position, true);
                    checkedPosition = position;
                } else {
                    map.remove(position);
                    if (map.size() == 0) {
                        checkedPosition = -1; //-1 代表一个都未选择
                    }
                }
                if (!onBind) {
                    notifyDataSetChanged();
                }
            }
        });
        onBind = true;
        if (map != null && map.containsKey(position)) {
            holder.mCheckBox.setChecked(true);
        } else {
            holder.mCheckBox.setChecked(false);
        }
        onBind = false;
    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        CheckBox mCheckBox;
        TextView mTextView;

        public ViewHolder(View itemView) {
            super(itemView);
            mCheckBox = (CheckBox) itemView.findViewById(R.id.checkbox);
            mTextView = (TextView) itemView.findViewById(R.id.textView);
        }
    }
}
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值