2012-03-25 38 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; 
}