大家好,将今天遇到的一个ListView或GridView中含有CheckBox时,CheckBox选中状态混乱的问题的解决方案记录一下,希望对大家有些帮助。
开发中常常会有ListView或者GridView中包含CheckBox的情况,当列表空间滚动时,稍不注意CheckBox的选中状态就会混乱,导致这样的原因是ListView或GridView本省的缓存,若不需要记录选中的数目,
则解决方案可以是:
- 在adapter里的getView方法里先调用holder.cbIamge.setOnCheckedChangeListener方法,
- 再调用holder.cbIamge.setChecked方法即可解决问题。(holder.cbIamge)是一个CheckBox对象。
若还要实时记录CheckBox选中了的数量,则上面的解决方案还是不管用,通过在网上的搜索,终于找到了解决方案,在此记录一下,该网址为:http://stackoverflow.com/questions/6100518/checkbox-auto-call-oncheckedchange-when-listview-scroll
该解决方案是:
- 在adapter中调用holder.cbIamge.setChecked()时先将CheckBox的监听设为空(holder.cbIamge.setOnCheckedChangeListener(null);)
- 再调用holder.cbIamge.setChecked()方法
- 最后重新设定CheckBox的监听holder.cbIamge.setOnCheckedChangeListener(new OnCheckedChangeListenerImpl(holder, position));
即可解决问题。
adapter的代码片段如下:
class AlbumAdapter extends BaseAdapter {
private Context context;
private List<AlbumItem> list;
private SparseBooleanArray selectArray = new SparseBooleanArray();
int selectSize = 0;
public AlbumAdapter(Context context, List<AlbumItem> list) {
this.context = context;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
AlbumViewHolder holder = null;
if (convertView == null) {
holder = new AlbumViewHolder();
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(R.layout.item_album, parent, false);
FrameLayout frameLayout = (FrameLayout) convertView.findViewById(R.id.item_layout);
AbsListView.LayoutParams layoutParams = (LayoutParams) frameLayout.getLayoutParams();
layoutParams.width = unitWidth;
layoutParams.height = unitWidth;
frameLayout.setLayoutParams(layoutParams);
ImageView ivImage = (ImageView) convertView.findViewById(R.id.iv_image);
View choseView = convertView.findViewById(R.id.chose_view);
CheckBox cbImage = (CheckBox) convertView.findViewById(R.id.cb_image);
holder.ivImage = ivImage;
holder.choseView = choseView;
holder.cbIamge = cbImage;
convertView.setTag(holder);
} else {
holder = (AlbumViewHolder) convertView.getTag();
}
holder.cbIamge.setOnCheckedChangeListener(null);
AlbumItem item = list.get(position);
holder.cbIamge.setChecked((selectArray.indexOfKey(position) >= 0) ? selectArray.get(position) : false);
if(holder.cbIamge.isChecked()) {
holder.choseView.setVisibility(View.VISIBLE);
} else {
holder.choseView.setVisibility(View.GONE);
}
holder.cbIamge.setOnCheckedChangeListener(new OnCheckedChangeListenerImpl(holder, position));
// imageLoader.loadDrawable(item.getUrl(), new ImageCallbackImpl(holder));
imageLoader.displayImage(item.getUrl(), holder.ivImage);
return convertView;
}
class ImageCallbackImpl implements ImageCallback {
private AlbumViewHolder holder;
public ImageCallbackImpl(AlbumViewHolder holder) {
super();
this.holder = holder;
}
@Override
public void imageLoaded(Bitmap bitmap) {
if (bitmap != null) {
holder.ivImage.setImageBitmap(bitmap);
} else {
holder.ivImage.setImageResource(R.drawable.ic_stub);
}
}
}
final class AlbumViewHolder {
ImageView ivImage;
CheckBox cbIamge;
View choseView;
}
class OnCheckedChangeListenerImpl implements
CompoundButton.OnCheckedChangeListener {
AlbumViewHolder holder;
int position;
public OnCheckedChangeListenerImpl(AlbumViewHolder holder, int position) {
super();
this.holder = holder;
this.position = position;
}
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
selectSize ++;
} else {
selectSize --;
}
if(selectSize <= 9) {
selectSize = selectSize < 0 ? 0 : selectSize;
if (isChecked) {
holder.choseView.setVisibility(View.VISIBLE);
} else {
holder.choseView.setVisibility(View.GONE);
}
selectArray.put(position, isChecked);
menuDone.setTitle(selectSize + "/9");
} else {
selectSize = selectSize > 9 ? 9 : selectSize;
holder.cbIamge.setChecked(false);
Toast.makeText(context, "只能选择9张图片", Toast.LENGTH_SHORT).show();
}
}
}
}