1. 程式人生 > >ListView 複用導致 CheckBox 選中狀態錯亂

ListView 複用導致 CheckBox 選中狀態錯亂

在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設定狀態上面。