2

使用this Expandable List checkbox example code作爲基線,我試圖保存並保持複選框狀態。然而,隨機複選框正在被選中或取消選中(觸發我的OnCheckedChangeListener以及新值),當我將它們滾動到視線之外時,最小化它們的組,甚至最小化/最大化附近的組!Android,複選框隨機選中/未選中可擴展列表

public Object getChild(int groupPosition, int childPosition) { 
    return colors.get(groupPosition).get(childPosition); 
} 

public long getChildId(int groupPosition, int childPosition) { 
    return (long)(groupPosition*1024+childPosition); // Max 1024 children per group 
} 

public View getChildView(final int groupPosition, final int childPosition, 
     boolean isLastChild, View convertView, ViewGroup parent) { 

    View v = null; 
    if(convertView != null) { 
     v = convertView; 
    } else { 
     v = inflater.inflate(R.layout.child_row, parent, false); 
    } 

    Color c = (Color)getChild(groupPosition, childPosition); 

    TextView color = (TextView)v.findViewById(R.id.childname); 
    if(color != null) { 
     color.setText(c.getColor()); 
    } 

    TextView rgb = (TextView)v.findViewById(R.id.rgb); 
    if(rgb != null) { 
     rgb.setText(c.getRgb()); 
    } 

    CheckBox cb = (CheckBox)v.findViewById(R.id.check1); 
    cb.setChecked(c.getState()); 
    cb.setOnCheckedChangeListener(new OnCheckedChangeListener() 
    { 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
     { 
      colors.get(groupPosition).get(childPosition).setState(isChecked); 
      context.setColorBool(groupPosition, childPosition, isChecked); 
      Log.d("ElistCBox2", "listitem position: " +groupPosition+"/"+childPosition+" "+isChecked); 
     } 
    }); 

    return v; 
} 

我不知道這段代碼可能是什麼原因造成的,所以我們歡迎任何關於包含在這裏的建議。我的代碼只有在嘗試保存值時才與原始代碼不同。

+0

我對ExpandableListViews中的CheckBox有這個確切的問題。一直在尋找答案。希望你的問題得到比我更多的迴應。 – jmease

+0

@jmease今天我評論了我的convertView代碼,並且問題消失了。我仍然有點不確定是否一切正常,我覺得應該使用ExpandableListView之外的東西來重寫UI,但代碼正在運行,所以我現在可能會保留原樣。我強烈建議你嘗試忽略convertview,看看它是否適合你。 –

回答

0

我的猜測是,當您的適配器正在創建視圖時,檢查偵聽器將在複選框視圖初始化時被調用。 Android中的許多小部件都是這樣工作的...偵聽器在視圖初始化時被調用。

我不知道爲什麼事情是這樣工作的,但它可能是讓客戶端代碼以一致的方式初始化自己。例如,該複選框是由用戶檢查還是被初始化爲檢查,運行相同的代碼。

來解決這個問題,你可以嘗試做這樣的事情在你的監聽器類IMPL設置一個標誌,讓你忽略第一次點擊,像,

cb.setOnCheckedChangeListener(new OnCheckedChangeListener() 
    { 
     private void first = true; 

     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
     { 
      if (first) { 
       first = false; 
       return; 
      } 

      colors.get(groupPosition).get(childPosition).setState(isChecked); 
      context.setColorBool(groupPosition, childPosition, isChecked); 
      Log.d("ElistCBox2", "listitem position: " +groupPosition+"/"+childPosition+" "+isChecked); 
     } 
    }); 

也確保你正確地重新在您的適配器中實施getView()時使用convertView。例如,

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View view = convertView; 
    if (view == null) { 
     view = inflater.inflate(R.layout.applications_item, null); 
    } 
+0

我增加了更多的源代碼。我相信我正確使用convertView。我不認爲'setOnCheckedChangeListener'標誌會做任何事情來阻止複選框被隨機更改,它只是不會保存更改。當我添加代碼時,「隨機更改」變成每個複選框,只是恢復到原來的狀態。 –

+0

在你的'getView()'方法中加入了斷點,以便了解是否正在使用converrtView,如果重新創建複選框比你想象的要多,並且創建複選框與被調用的偵聽器之間存在關聯。 –

0

這是一個非常古老的問題,但我有同樣的問題,努力使這裏是我的人尋找答案:

最簡單的方法是使用CheckBox.onClickListener而不是onCheckedChangeListener。

這對於重新排列邏輯而言只是輕度惱人的,但會確保當方塊隨機取消選中時(例如通過擴展相鄰組),事件不會觸發。

老實說,我認爲這應該被視爲一個錯誤,即使我確定這個行爲可以從Android來源解釋。

相關問題