2010-10-24 65 views
8

我已經通過擴展SimpleCursorAdapter創建了自定義ListView。 結果是IMAGE + CheckedTextView(文本+複選框)。Android單擊listItem檢查錯誤的複選框

當我長時間點擊一個項目,一切工作正常 - 我得到正確的ID和點擊項目的細節。

當我嘗試將某個項目標記爲已選中但它檢查錯誤的複選框時,會出現此問題。

例如:我在我的名單上有9個項目,排序1-9。如果我點擊listItem 1,就會檢查第9行的複選框。如果我點擊第4項,第6行的複選框正在被檢查,如果我點擊中間線,它正在被檢查。

很明顯,我在這裏丟失了一些東西:) 記得當我長時間點擊行(contextMenu打開)時,一切都很好。

這是聽衆:

lv.setOnItemClickListener(new OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       CheckedTextView markedItem = (CheckedTextView) view.findViewById(R.id.btitle); 

       if (!markedItem.isChecked()) { 
        markedItem.setChecked(true); 
       } else { 
        markedItem.setChecked(false); 
       } 

      } 
     }); 

感謝任何幫助!

讓我知道如果您需要我發佈更多的代碼。

謝謝!

順便說一句,如果我點擊不止一臺...的PARTY繼續......沒有明顯的順序...

編輯:適配器代碼

public class ImageCursorAdapter extends SimpleCursorAdapter { 

    private Cursor c; 
    private Context context; 

    private String url; 
    private TextView bUrl; 

    public ImageCursorAdapter(Context context, int layout, Cursor c, 
      String[] from, int[] to) { 
     super(context, layout, c, from, to); 
     this.c = c; 
     this.context = context; 
    } 

    public View getView(int pos, View inView, ViewGroup parent) { 
     View v = inView; 
     if (v == null) { 
      LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = inflater.inflate(R.layout.image_list, null); 
     } 

     this.c.moveToPosition(pos); 

     final TextView bTitle = (TextView) v.findViewById(R.id.btitle); 
     String bookmark = this.c.getString(this.c.getColumnIndex(Browser.BookmarkColumns.TITLE)); 


     byte[] favicon = this.c.getBlob(this.c.getColumnIndex(Browser.BookmarkColumns.FAVICON)); 

     if (favicon != null) { 
      ImageView iv = (ImageView) v.findViewById(R.id.bimage); 
      iv.setImageBitmap(BitmapFactory.decodeByteArray(favicon, 0, favicon.length)); 
     } 
     bTitle.setText(bookmark); 

     return (v); 
    } 
} 
+0

向我們展示您的適配器 – Falmarri 2010-10-24 22:10:14

+0

已編輯的問題。謝謝。 – 2010-10-24 22:12:43

+0

你記錄聽者的位置值嗎?你有其他聽衆嗎? – Jim 2010-10-24 22:27:32

回答

11

梅拉是正確的 - 問題必須處理ListView重用視圖的方式。這並不像存在CheckedTextView對象的9個實例,每個視圖有一個實例。相反,在所有行中都有一個重複使用。因此,您不能依賴CheckedTextView對象來保存是否檢查項目的狀態。你需要一些額外的數據結構來保存一個給定的行是否被選中。例如,

ArrayList<Boolean> checkedStates = new ArrayList<Boolean>(); 

當且僅當ith行應檢查ith元素是真實的。然後你itemClickListener內:

lv.setOnItemClickListener(new OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      boolean currentlyChecked = checkedStates.get(position); 
      checkedStates.set(position, !currentlyChecked); 
      // Refresh the list 
     } 
    }); 

然後在您的視圖代碼:

public View getView(int pos, View inView, ViewGroup parent) { 
    View v = inView; 
    if (v == null) { 
     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = inflater.inflate(R.layout.image_list, null); 
    } 

    this.c.moveToPosition(pos); 

    final TextView bTitle = (TextView) v.findViewById(R.id.btitle); 
    String bookmark = this.c.getString(this.c.getColumnIndex(Browser.BookmarkColumns.TITLE)); 


    byte[] favicon = this.c.getBlob(this.c.getColumnIndex(Browser.BookmarkColumns.FAVICON)); 

    if (favicon != null) { 
     ImageView iv = (ImageView) v.findViewById(R.id.bimage); 
     iv.setImageBitmap(BitmapFactory.decodeByteArray(favicon, 0, favicon.length)); 
    } 
    bTitle.setText(bookmark); 


    // Change the state of the checkbox to match that of the row's checked state. 
    // This check box item is reused for every row, so we need to reset its state each 
    // time the row is rendered. 
    CheckedTextView markedItem = (CheckedTextView) view.findViewById(R.id.btitle); 
    markedItem.setChecked(checkedStates.get(pos)); 


    return (v); 
} 

這應該解決您的問題。另一種方法是將該行是否被檢查的邏輯移動到行代表的域對象中。那將是我的首選。

+0

謝謝你的回覆!嘗試了你的建議,無論我做了什麼,我都得到了「IndexOutOfBoundsExeption」的強制關閉。 任何想法? – 2010-10-25 00:16:52

+0

您需要在某些時候將初始條目添加到ArrayList。當你知道有多少項目,例如'for(int i = 0; i I82Much 2010-10-25 01:55:33

+0

好的非常感謝你。會嘗試這個! – 2010-10-25 06:39:31