滑動ListView時,CheckBox控件錯亂

這是一個很普遍的情況,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;
	}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章