在开发类似购物车编辑功能时遇到了CheckBox选择状态复用问题。
一言不合先上图:

范例.png
写法一:
CheckBox checkBox = holder.getView(R.id.checkbox);
checkBox.setTag(position);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
}
});
很显然,我们并没有用代码去控制CheckBox的checked状态,因此导致ListView滑动的时候复用了CheckBox。所以我们可以加入Map集合,控制CheckBox显示状态。key记录position或者唯一id,value记录true或false的状态。
写法二:
//注意:全局定义
private HashMap<Long, Boolean> checkedMap = new HashMap<>();
/*以下是Adapter中代码*/
CheckBox checkBox = holder.getView(R.id.checkbox);
if (checkedMap.containsKey(getItem(position).getRelationId())
&& checkedMap.get(getItem(position).getRelationId())) {
//如果Map中存在此消息,并且已选中
checkBox.setChecked(true);
} else {
checkBox.setChecked(false);
}
checkBox.setTag(position);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int tag = (int) buttonView.getTag();
checkedMap.put(getItem(tag).getRelationId(), isChecked);
notifyDataSetChanged();
}
});
依照写法二我们可以在onCheckedChanged方法中设置Map的key和value,然后调用notifyDataSetChanged()通知Adapter刷新状态。
然而并没有什么卵用

并无卵用.jpg
当我们给CheckBox设置不同状态以后,滑动ListView时,发现CheckBox的状态发生了错乱,通过断点调试,发现Map中的数据是在改变的,从而导致CheckBox状态错乱,而真正能修改Map的地方只有onCheckedChanged方法,果不其然,滚动竟然导致了onCheckedChanged方法执行。
那么问题来了,咋搞!!!
原来是代码顺序出现了问题,我们先设置了CheckBox状态,然后再去设置了状态改变监听器。由于状态的改变,导致onCheckedChanged方法执行。
写法三
checkBox.setTag(position);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int tag = (int) buttonView.getTag();
checkedMap.put(getItem(tag).getRelationId(), isChecked);
notifyDataSetChanged();
}
});
if (checkedMap.containsKey(getItem(position).getRelationId())
&& checkedMap.get(getItem(position).getRelationId())) {
//如果Map中存在此消息,并且已选中
checkBox.setChecked(true);
} else {
checkBox.setChecked(false);
}
搞定!
先去嘘嘘~