2011-03-25 73 views
6

我想創建一個自定義列表,其中將有複選框,允許您從列表中選擇多個項目。與複選框問題的自定義列表視圖

帶有複選框的列表顯示正常,但是如果我選中了一個複選框,然後再滾動列表中的其他項目也會被選中。

它基本上是相同的問題,因爲here

我明白,這事做與Android的方式回收的觀點,但我不能看到如何解決這個問題!有人可以幫我嗎?

謝謝 - Mike

回答

5

您需要一個數據結構來跟蹤哪些行被檢查。這可以像bool[] checked那樣簡單。

在您的getView中,請確保您將複選框狀態設置爲checked[position]的內容。您也應該在getView的複選框中輸入set an OnCheckedChangedListener,以便他們使用更新您的數據。

是的,ListView中的行會被回收,所以在離開getView之前,請確保爲一行填充所有適當的數據。

+1

優秀的作品就像一個魅力!我不知道每次滾動時都會調用getView方法!我認爲整個列表被初始化,然後getView方法再也不會被調用了! – mixkat 2011-03-25 22:06:34

+0

我以爲我解決了這個問題,但我錯了。它很奇怪,因爲在setOnCheckedChangeListener中,我必須以相反的方式工作,即如果isChecked,則將數組的相應字段設置爲false,否則設置爲true。但是當我必須檢查哪些盒子被檢查時,所有東西都被搞亂了。注意:如果我正確設置它,即當盒子被選中時將數組字段設置爲真,那麼如果我向下滾動並且再次備份,則丟失所有東西。任何想法爲什麼發生這種情況? – mixkat 2011-03-26 18:06:42

+0

您確定即使對於循環視圖調用'setChecked'?換句話說,if(convertView == null){/ *充滿視圖* /}/*填充視圖,無論在if語句之外再循環/不可循環* /' – 2011-03-26 22:42:23

0

創建一個ArrayList<Integer>。將OnCheckChangedListener添加到您的複選框。在更改的方法中,將列表視圖position添加到ArrayList<Integer>或將其刪除。

在您的getView方法中,檢查ArrayList<Integer>是否包含當前列表視圖position。如果它包含該位置,則將選中項設置爲true,否則爲false。

每當您單擊一個複選框時,請從ArrayList中添加或刪除Integer

2

您可以嘗試實現OnClickListener複選框而不是OnCheckChangedListener。它爲我工作。

0

檢查下面的代碼 -

public View getView(int position, View convertView, ViewGroup parent){ 
      View view = convertView; 
      ViewHolder holder = new ViewHolder(); 

      if(view == null){ 

       view = inflater.inflate(R.layout.list_callcycle_blue, null);     
       holder.llContainer = (LinearLayout) view.findViewById(R.id.ll_container); 
       holder.lblLabel = (TextView) view.findViewById(R.id.txt_desc); 
       holder.cb = (CheckBox) view.findViewById(R.id.cb_store); 

       view.setTag(holder); 
      } else { 
       holder = (ViewHolder) view.getTag(); 
      } 

      final Object data = getItem(position); 
      holder.lblLabel.setText(data.getDescription()); 

      holder.cb.setTag(position); 
      holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { 

       @Override 
       public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 

        int position = (Integer) buttonView.getTag(); 
        objects.get(position).setChecked(buttonView.isChecked()); 
       } 
      }); 
      holder.cb.setChecked(isChecked(position)); 

      return view; 
     } 

始終牢記,利用變化holder.cb.setOnCheckedChangeListener()任意監聽它的設置數據之前,在我們的情況下,它是holder.cb.setChecked()

原因:當我們滾動,listview將回收視圖,所以如果在偵聽器之前使用了setchecked,那麼它將根據舊的偵聽器來選擇值。如果我們監聽後設置它,然後它會採取最新值

編輯的零件 下面部分將展示用於檢索isChecked()setChecked()方法是如何檢查的數據

/* 
* This function is in your Custom Adapter Class 
*/ 
private boolean isChecked(int position){ 
    return object(position).isChecked(); 
} 


/** 
* Getter Setter Class/Data Model Class that defines your object 
*/ 
private class MyObject{ 
    private boolean isChecked; 
    private String a, b, c, orWhateverYourObjectNeeds; 

    public void setChecked(boolean isChecked){ 
     this.isChecked = isChecked; 
    } 

    public boolean isChecked(){ 
     return isChecked 
    } 
} 
+0

嗨吉特帕特爾,你能解釋你如何從「對象」和「isChecked(位置)」從你的代碼在上面?謝謝 – 2015-02-27 15:12:49

+0

已經編輯好久了。忘了溝通,對不起 – 2015-04-12 09:08:37

相關問題