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

来源:互联网 发布:金庸对悟空传评价知乎 编辑:程序博客网 时间:2024/06/05 02:42

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

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

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

此时适配器中的代码

@Overridepublic void onBindViewHolder(ViewHolder holder, final int position) {    holder.mTextView.setText(mList.get(position));}

想要解决勾选混乱问题,可以使用集合添加被勾选的CheckBox位置,然后集合中有的位置则设置为被勾选,没有的位置就设置不被勾选

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

此时的代码

private Map<Integer, Boolean> map = new HashMap<>();@Overridepublic 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<>();@Overridepublic 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;@Overridepublic 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);        }    }}

阅读全文
3 0
原创粉丝点击