ListView 複用導致 CheckBox 選中狀態錯亂
阿新 • • 發佈:2018-11-02
在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設定狀態上面。