现在的位置: 首页 > 综合 > 正文

滑动ListView时,CheckBox控件错乱

2018年05月25日 ⁄ 综合 ⁄ 共 2576字 ⁄ 字号 评论关闭

这是一个很普遍的情况,ListView的每一个View中包含CheckBox控件,在滑动屏幕时,原来点选的CheckBox貌似会发生变化,莫名其妙地乱窜:原来选中的变为没选中;原来没选中的变成选中,每滑动一下,就改变一次。

我们先来分析一下CheckBox会错乱的原因,我们在显示ListView的每一个View时,使用的是BaseAdapter的getView()方法,getView()方法的第二个参数View convertView,是会被重复使用的,也就是当滑动时产生新的View时,首先判断convertView是否为null,为null则inflate,不为null就使用已经生成的convertView。

知道了问题产生的原因,我们来说一下解决问题的思路。我一共想了两种解决策略:

1:第一次生成convertView时,保存到一个ArrayList<HashMap<Integer,View>> vmap中,Integer为该convertView对应的position,下一次getView()时,通过vmap.get(position)取得已经存在的convertView,代码如下:

        private SparseArray<View> vmap = new SparseArray<View>();
	
	@Override
	public View getView(int position, View convertView, android.view.ViewGroup parent){	
		     
			viewHolder viewholder = null;
			
			//Inflate view
			if(vmap.get(position)==null){
				viewholder = new viewHolder();
				convertView = mInflater.inflate(R.layout.list_item,null);
				viewholder.waybill = (TextView)convertView.findViewById(R.id.waybill);
				viewholder.addtime = (TextView)convertView.findViewById(R.id.addtime);
				viewholder.checkbox = (CheckBox)convertView.findViewById(R.id.checkbox);
				convertView.setTag(viewholder);
				vmap.put(position, convertView);
			}else{
				convertView = vmap.get(position);
				viewholder = (viewHolder)convertView.getTag();
			}
			return convertView;
	}		
	
	/**
	 * 私有化View控件
	 */
	public static class viewHolder{
		public TextView waybill;
		public TextView addtime;
		public CheckBox checkbox;
	}

这种方法可以解决CheckBox状态错乱的问题,但是有一个问题:有时候点击了CheckBox后,必须要滑动屏幕CheckBox的状态才会生效,还没有找到解决方法。

2:设置CheckBox的setOnCheckedChangeListener()事件,将每一个CheckBox的状态保存到一个ArrayList<HashMap<Integer,boolean>>数组中,Integer为该convertView对应的position,代码如下:

        public static SparseBooleanArray checked = new SparseBooleanArray();
	@Override
	public View getView(int position, View convertView, android.view.ViewGroup parent){	
		    viewHolder viewholder = null;
			//Inflate view
			if(convertView == null){
				viewholder = new viewHolder();
				convertView = mInflater.inflate(R.layout.list_item,null);
				viewholder.waybill = (TextView)convertView.findViewById(R.id.waybill);
				viewholder.addtime = (TextView)convertView.findViewById(R.id.addtime);
				viewholder.checkbox = (CheckBox)convertView.findViewById(R.id.checkbox);
				convertView.setTag(viewholder);
			}else{
				viewholder = (viewHolder)convertView.getTag();
			}

			final int mposition = position;
			viewholder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener(){
				@Override
				public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
					//TODO Auto-generated method stub
					if(isChecked)
                    {  
						checked.put(mposition, isChecked);
                    }else{
                        checked.delete(mposition);
                    }
 				}
			});
			//根据保存的状态设置CheckBox
			viewholder.checkbox.setChecked(checked.get(position)==true ? true : false);			
	}		
	
	/**
	 * 私有化View控件
	 */
	public static class viewHolder{
		public TextView waybill;
		public TextView addtime;
		public CheckBox checkbox;
	}

抱歉!评论已关闭.