ListView中CheckBox复用问题
2016-09-08 本文已影响699人
小编
在开发类似购物车编辑功能时遇到了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);
}
搞定!
先去嘘嘘~