2012-03-25 43 views
6

我一個定製Listview(無重寫getView()法)與每個項目在ListView具有以下佈局力列表視圖不重用次(複選框)

contactlayout.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="horizontal" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" android:weightSum="1"> 
    <CheckBox android:id="@+id/checkBox1" android:text="CheckBox" android:layout_width="134dp" android:layout_height="108dp" android:focusable="false"></CheckBox> 
    <LinearLayout android:id="@+id/linearLayout1" android:layout_height="match_parent" android:orientation="vertical" android:layout_width="87dp" android:layout_weight="0.84" android:weightSum="1" > 
     <TextView android:text="TextView" android:layout_height="wrap_content" android:layout_width="match_parent" android:id="@+id/name" android:layout_weight="0.03"></TextView> 
     <TextView android:text="TextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/phone"></TextView> 
     <TextView android:text="TextView" android:layout_height="wrap_content" android:layout_weight="0.03" android:layout_width="match_parent" android:id="@+id/contactid" android:visibility="invisible"></TextView> 
    </LinearLayout> 
</LinearLayout> 

我我通過以下方式使用SimpleCursorAdapter填充Listview ...

Cursor c = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME); 

     String from[] = new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,ContactsContract.CommonDataKinds.Phone.NUMBER,ContactsContract.CommonDataKinds.Phone.CONTACT_ID}; 
     int to[] = new int[]{R.id.name,R.id.phone,R.id.contactid}; 
     SimpleCursorAdapter s = new SimpleCursorAdapter(this,R.layout.contactlayout,c,from,to); 
     lv.setAdapter(s); 

點擊一個按鈕我正在閱讀所有複選框的狀態。問題是,如果我檢查一個CheckBox下線的其他人自動檢查。我知道這是重複使用視圖。我如何避免它?在這種情況下,我甚至不會重寫getView()方法,所以我想知道是否還有辦法實現我想要的?

回答

最後我實現什麼建議...... @sastraxi

@Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View view = super.getView(position, convertView, parent); 

     final CheckBox checkBox = (CheckBox) view.findViewById(R.id.checkBox1); 
     final TextView name = (TextView) view.findViewById(R.id.name); 
     final TextView contactId = (TextView) view.findViewById(R.id.contactid); 
     final int pos = position; 
     checkBox.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       // TODO Auto-generated method stub 
       if(checkBox.isChecked()) 
       { 
        checkList.add(String.valueOf(pos)); 
        nameList.add(name.getText().toString()); 
        contactList.add(contactId.getText().toString()); 
        Log.i("Chk added",String.valueOf(pos)); 
       } 
       else 
       { 
        checkList.remove(String.valueOf(pos)); 
        nameList.remove(name.getText().toString()); 
        contactList.remove(contactId.getText().toString()); 
        Log.i("Un Chk removed",String.valueOf(pos)); 
       } 
      } 
     }); 

     if(checkList.contains(String.valueOf(pos))) 
     { 
      checkBox.setChecked(true); 
     } 
     else 
     { 
      checkBox.setChecked(false); 
     } 

     return view; 
    } 
+0

我們可以看到連接到'ListView'任何單擊處理這兩種方法? – sastraxi 2012-03-25 06:09:50

+0

@sastraxi:沒有添加任何Listener到'Listview',我只是讀取所有複選框的狀態,當用戶點擊一個按鈕。 – 2012-03-25 06:11:54

+1

非常感謝。它也解決了切換按鈕的問題。 – zawhtut 2012-08-10 12:48:00

回答

3

啊,我明白了問題所在。

創建一個新的類,它擴展SimpleCursorAdapter,說CheckboxSimpleCursorAdapter,並覆蓋getView這樣:

public View getView(int position, View convertView, ViewGroup parent) { 
    View view = super.getView(position, convertView, parent); 
    CheckBox checkBox = (CheckBox) view.findViewById(R.id.CheckBox1); 
    checkBox.setChecked(getIsThisListPositionChecked(position)); 
    return view; 
} 

如果你還沒有使用佈局,其頂級View實現Checkable,你必須自己做的一切。這包括清除狀態(在這種情況下),因爲默認實現重用了已檢查的View - 正如您正確直覺的那樣。

編輯:使用這個新的代碼,並實現一個protected boolean getIsThisListPositionChecked(int position)方法,該方法返回該項目是否當前被檢查(或類似的東西)。我希望我已經足夠清晰 - 你需要弄清楚是否應該根據您的型號進行檢查,然後在創建View時進行設置。

+0

讓我試試.. – 2012-03-25 06:18:49

+0

如果我向下滾動,它會取消選中所有選中的項目。當用戶滾動回到這些項目時,如何重新檢查它們? – 2012-03-25 06:29:20

+0

我更新了我的答案 - 道歉不完整。基本上,不用'setChecked(false)',你需要'setChecked(不管模型說這個項目的檢查狀態應該是現在)'。 – sastraxi 2012-03-25 06:32:41

2

它總是更好地重複使用的意見。你想要實現的功能可以通過代碼中的一些調整來完成。您需要通過使用另一個變量列表(每個列表項的布爾值)來記錄您的複選框的選中狀態。

+0

是的,但我不希望用戶查看項目,即使他們沒有檢查它。 – 2012-03-25 06:14:41

+0

@Shashank - 除了設置字符串之外,還必須使用變量列表Kumar描述的方式專門檢查並設置複選框的狀態。 – 2012-03-25 06:18:39

+0

@Peter Ajtai:我會用這種方法做這一切? 'getView'? – 2012-03-25 06:30:55

6

另一種方式來迫使不重用的意見,加入你的光標適配器如下:

@Override 
    public int getItemViewType(int position) { 
     return position; 
    } 

    @Override 
    public int getViewTypeCount() { 
     return 500; 
    } 

但是,是的,你應該重用的意見只要有可能。在我的特殊情況下,我將圖像添加到視圖中,並且不強制不重用視圖,而是在重用視圖中重新渲染它們。

+0

我認爲這是保持性能並保持不重複使用的最佳方式。 – 2015-02-11 18:00:30

1

覆蓋在你的適配器類

@Override 
public int getViewTypeCount() 
{     
    return getCount(); 

} 

@Override 
public int getItemViewType(int position) 
{ 
return position; 
}