ListView 复用导致 CheckBox 选中状态错乱

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lijia1201900857/article/details/79130544

在ListView嵌套CheckBox 等一些有标记的View时,如果不做处理,在ListView 滑动的时候,

会造成View的选中状态错乱。

比如:

可以看到 刚开始选中了demo2 和demo3。滑动到下一页的时候,demo10 和demo11 也被选中。

当然要解决这个问题很简单。只需要在 适配器Adapter 中对CheckBox的选中状态做一下记录。上代码:


public class MyAdapter extends BaseAdapter{
		private List<String> mList;
		private Context mContext;
		//步骤1
		private Map<Integer, Boolean> cbState;// 存放 CheckBox 的选中状态
		
		public MyAdapter(Context mContext,List<String> mList) {
			this.mContext=mContext;
			this.mList=mList;
			cbState=new HashMap<Integer, Boolean>();
		}

		@Override
		public int getCount() {
			return mList!=null?mList.size():0;
		}

		@Override
		public Object getItem(int position) {
			return mList!=null?mList.get(position):null;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(final int position, View convertView, ViewGroup parent) {
			ViewHolder holder = null;
			if(convertView==null){
				convertView=LayoutInflater.from(mContext).inflate(R.layout.demo_item, parent,false);
				holder=new ViewHolder(convertView);
				convertView.setTag(holder);
			}else{
				holder=(ViewHolder)convertView.getTag();
			}
			holder.textView.setText(mList.get(position));
			
			// 步骤2 对checkbox 的选中状态进行监听,选中时,存入Map 集合,取消选中,则从集合中移除
			holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
				
				@Override
				public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
					
					if(isChecked){
						cbState.put(position, true);
					}else{
						cbState.remove(position);
					}
				}
			});
			
		// 步骤3 对Map集合进行判断,处理checkBox 的选中状态
			if(cbState!=null&&cbState.containsKey(position)){
				holder.checkBox.setChecked(true);
			}else{
				holder.checkBox.setChecked(false);
			}
			return convertView;
		}
		private class ViewHolder{
			private TextView textView;
			private CheckBox checkBox;
			public ViewHolder(View view) {
				if(view==null)
					return;
				textView=(TextView)view.findViewById(R.id.demo_tv);
				checkBox=(CheckBox)view.findViewById(R.id.demo_cb);
			}
		}
	}
 这样写就可以解决问题。

注意:

如果 步骤2 和步骤3 的顺序写反了,即把对checkBox 的监听方法,写到了checkBox 设置状态的下面了。仍然会导致选中状态错乱。

如图所示:


可以看到 我选中了demo0 和demo1 ,滑下去在滑上来,选中状态就变成了未选中。

通过抓Log,发现,如果两者的顺序写反了,当状态再次改变时,

setOnCheckedChangeListener

监听方法中的position,使用的是上次点击时的postion 。

具体原因还没搞明白,以后会补充。

记住,两者的顺序一定不要写反。要把监听方法写在CheckBox设置状态上面。




猜你喜欢

转载自blog.csdn.net/lijia1201900857/article/details/79130544