Android中ListView、GridView里的CheckBox混乱且记录选中数量不准确的解决方案

大家好,将今天遇到的一个ListView或GridView中含有CheckBox时,CheckBox选中状态混乱的问题的解决方案记录一下,希望对大家有些帮助。

开发中常常会有ListView或者GridView中包含CheckBox的情况,当列表空间滚动时,稍不注意CheckBox的选中状态就会混乱,导致这样的原因是ListView或GridView本省的缓存,若不需要记录选中的数目,

则解决方案可以是:

  1. 在adapter里的getView方法里先调用holder.cbIamge.setOnCheckedChangeListener方法,
  2. 再调用holder.cbIamge.setChecked方法即可解决问题。(holder.cbIamge)是一个CheckBox对象。

若还要实时记录CheckBox选中了的数量,则上面的解决方案还是不管用,通过在网上的搜索,终于找到了解决方案,在此记录一下,该网址为:http://stackoverflow.com/questions/6100518/checkbox-auto-call-oncheckedchange-when-listview-scroll 

该解决方案是:

  1. 在adapter中调用holder.cbIamge.setChecked()时先将CheckBox的监听设为空(holder.cbIamge.setOnCheckedChangeListener(null);)
  2. 再调用holder.cbIamge.setChecked()方法
  3. 最后重新设定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();
				}
			}
		}
	}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值