這是一個很普遍的情況,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;
}