ListView中CheckBox复用问题

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


ListView中CheckBox复用问题_第1张图片
范例.png

写法一:

CheckBox checkBox = holder.getView(R.id.checkbox);
checkBox.setTag(position);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    }
});

很显然,我们并没有用代码去控制CheckBoxchecked状态,因此导致ListView滑动的时候复用了CheckBox。所以我们可以加入Map集合,控制CheckBox显示状态。key记录position或者唯一idvalue记录truefalse的状态。

写法二:

//注意:全局定义
private HashMap 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方法中设置Mapkeyvalue,然后调用notifyDataSetChanged()通知Adapter刷新状态。

然而并没有什么卵用


ListView中CheckBox复用问题_第2张图片
并无卵用.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);
}

搞定!
先去嘘嘘~

你可能感兴趣的:(ListView中CheckBox复用问题)