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

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

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

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

RecyclerView中使用CheckBox勾选混乱问题解决以及单选功能的实现_第1张图片

此时适配器中的代码

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

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

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

RecyclerView中使用CheckBox勾选混乱问题解决以及单选功能的实现_第2张图片

此时的代码

private Map, 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加入进去,在通知适配器更新。

效果如下:

RecyclerView中使用CheckBox勾选混乱问题解决以及单选功能的实现_第3张图片

错误示例:

private Map, 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 {

    private List mList;
    private Context mContext;

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

    public CheckBoxAdapter(Context context, List 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);
        }
    }
}

你可能感兴趣的:(Android)