2011-09-01 98 views
1

我不確定在我的代碼中它是否僅僅是我或其他東西是錯誤的。我在自定義列表視圖中填充所有手機聯繫人,並且一切都很好,直到它填充。自定義列表視圖有一個複選框,以便可以選擇多個項目。問題是,當我說有30個聯繫人加載在列表視圖中,我選擇第一個聯繫人,我向下滾動,我看到第11和第21聯繫人也被選中。我不確定爲什麼會發生這種不尋常的問題中的任何信息會有幫助。自定義列表視圖和適配器和列表視圖選擇去瘋狂?

這裏的XML代碼

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" 
android:layout_width="match_parent" 
android:layout_height="match_parent"> 
    <ListView android:id="@android:id/list" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:drawSelectorOnTop="false" 
     android:choiceMode="multipleChoice"/> 
    <TextView android:id="@+id/empty" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="@string/main_no_contacts" 
     android:textColor="@color/white"/> 
    </LinearLayout> 

自定義佈局

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:id="@+id/rlContactListRowMain" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:padding="5dp"> 
<ImageView android:id="@+id/ivContactIconRow" 
      android:src="@drawable/droid_small" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content"/> 
<RelativeLayout android:id="@+id/rlContactListRowChild" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_toRightOf="@+id/ivContactIconRow" 
       android:layout_alignTop="@+id/ivContactIconRow"> 
       <TextView android:text="Vikram Ramanathan" 
          android:layout_width="wrap_content" 
          android:layout_height="wrap_content" 
          android:id="@+id/tvRowContactName" 
          android:paddingLeft="10dip" 
          android:textColor="@color/white"/> 
       <TextView android:text="Phone Numbers: " 
          android:layout_width="wrap_content" 
          android:layout_height="wrap_content" 
          android:paddingLeft="10dip" 
          android:id="@+id/tvRowContactPhone" 
          android:layout_below="@+id/tvRowContactName" 
          android:textColor="@color/white"/>                                 
</RelativeLayout> 
<CheckBox android:id="@+id/chkSelectContact" 
      android:layout_height="wrap_content" 
      android:text="" 
      android:layout_width="wrap_content" 
      android:layout_alignParentRight="true"></CheckBox>       
    </RelativeLayout> 

的Java代碼

super.onCreate(savedInstanceState); 
    setContentView(R.layout.listcontacts); 
    phoneContactList = new ArrayList<PhoneContactInfo>(); 
    this.m_adapter = new PhoneContactListAdapter(this, R.layout.listcontacts_row, phoneContactList); 
    setListAdapter(this.m_adapter); 

適配器代碼是

View v = convertView; 
    if (v == null) 
    { 
     LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.listcontacts_row, null); 
    } 

    PhoneContactInfo phoneContactInfo = phoneContacts.get(position); 

    if (phoneContactInfo != null) 
    { 
     TextView tvContactName = (TextView) v.findViewById(R.id.tvRowContactName); 

     if (tvContactName != null) 
     { 
      tvContactName.setText(phoneContactInfo.getContactName()); 
     } 

     TextView tvContactNumber = (TextView) v.findViewById(R.id.tvRowContactPhone); 

     if (tvContactNumber != null) 
     { 
      tvContactNumber.setText(phoneContactInfo.getContactNumber()); 
     } 
    } 
    v.setTag(phoneContactInfo); 
    phoneContactInfo = null; 
    return v; 

回答

1

我認爲問題是,當你填充項目時,你更新TextViews,你不更新CheckBox。列表項目的佈局被重用,這就是爲什麼下一個項目被CheckBox檢查。嘗試在列表或自定義類中保存每個CheckBox狀態,並保存或從此處加載它。

+0

謝謝你,你是對的,國家沒有被保存。我在這裏有一個解決方法(http://stackoverflow.com/questions/4803756/android-cursoradapter-listview-and-checkbox),但最後一個代碼是在狀態被動態加載的地方給出的,在那裏有兩個複選框。我不知道什麼時候我應該有第二個複選框。在相同的佈局是正確的? – vikramjb

+0

不要在那裏看到兩個複選框。有一個ArrayList 它保持ListView中每個項目的CheckBox狀態。 –

+0

yeap我看錯了。它工作完美。謝謝你,更強大。感謝你的回答:) – vikramjb

1

我認爲Mighter是對的。您可以通過刪除if (v == null)檢查並每次從頭開始重新創建視圖來快速確認。當您使用回收視圖時,您將(即convertView)確保在適當時重置所有視圖。

根據此列表的性能級別,您可能還希望使用ViewHolder模式,並且不要在每次調用getView()時調用findViewById。我推薦Google I/O 2010發表這個演講,其中詳細介紹了ListViews和適配器: http://www.youtube.com/watch?v=wDBM6wVEO70

+0

Mightier是對的,它的重用。當我移除條件時,它會在我滾動時重置。 +1視頻。 – vikramjb