一.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);
}
}
}