场景:当ListView中嵌套CheckBox,在滑动过程中,遇到滑动过程中,CheckBox选中状态错乱。
分析:ListView在滑动过程中,每个item都需要调用getView(int position, View convertView, ViewGroup parent)方法,而这个方法传入的 convertView 是在屏幕滑动过程中不断复用的,以减少 item 重新创建的内存消耗。但同时由于 convertView 的复用,也造成了我们的 CheckBox 展示状态默认复用前的状态。我们平时在 ListView 中出现的滑动过程中图片加载 闪烁也是同理。
优化方案:
本文仅以 ListView 支持单选为例:
1. 在实体类中添加一个参数:
public boolean is_Checked = false;
2. 在Adapter添加CheckBox状态监听
// 默认选中下标
private int index = -1;
@Override
protected View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
if (convertView == null) {
viewHolder = new ViewHolder();
convertView = mInflater.inflate(R.layout.item_related_fields_left, null);
viewHolder.cbTitle = (CheckBox) convertView.findViewById(R.id.tv_relative_fields_tag);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
CircleEntity circleEntity = mList.get(position);
viewHolder.cbTitle.setText(circleEntity.name);
viewHolder.cbTitle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b){
if (index != -1 ){ //判断是否被选中
mList.get(index).is_Checked = false;
}
index = position;
mList.get(index).is_Checked = true;
mIOnCurrentFragment.currentIndex(position);
notifyDataSetChanged();
}else {
if (index == position) { // 禁止取消当前项
compoundButton.setChecked(true);
}
}
}
});
//无默认选中项时:默认选中第一个
if (index == -1)
index= position;
if (index == position)
viewHolder.cbTitle.setChecked(true);
else
viewHolder.cbTitle.setChecked(circleEntity.is_Checked);
return convertView;
}
public class ViewHolder {
public CheckBox cbTitle;
}
此方案适用于商品选择标签,(ListView + Fragment) 进行左右联动的场景