【问题标题】:Custom ListView and Adapter and Listview selection goes bonkers?自定义 ListView 和 Adapter 以及 Listview 选择变得疯狂?
【发布时间】:2011-11-08 02:56:12
【问题描述】:

我不确定是我自己还是我的代码中有其他问题。我正在自定义列表视图中填充所有电话联系人,并且在填充之前一切都很好。自定义列表视图有一个复选框,以便可以选择多个项目。问题是当我说在列表视图中加载了 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;

【问题讨论】:

    标签: android android-listview


    【解决方案1】:

    我认为问题在于,当您填充项目时,您会更新 TextViews 而不会更新 CheckBox。您的列表项布局被重用,这就是下一个项目选中 CheckBox 的原因。尝试为列表或自定义类中的每个保存 CheckBox 状态,然后从那里保存或加载它。

    【讨论】:

    • 谢谢Mightier,你说得对,状态没有被保存。我在这里有一个解决方法(stackoverflow.com/questions/4803756/…),但是在动态加载状态的位置给出的最后一个代码,有两个复选框。我不确定什么时候应该有第二个复选框。在同一个布局吧?
    • 那里看不到两个复选框。有一个 ArrayList 为 ListView 中的每个项目保留 CheckBox 状态。
    • 是的,我看错了。它工作得很好。谢谢你,更强大。感谢您的回答:)
    【解决方案2】:

    我认为梅特是对的。您可以通过删除if (v == null) 检查并每次都从头开始重新创建视图来快速确认这一点。当您使用回收视图时,您将(即 convertView)您应该确保在适当的情况下重置所有视图。

    根据此列表的性能级别,您可能还希望使用 ViewHolder 模式,而不是在每次调用 getView() 时调用 findViewById。我推荐 Google I/O 2010 上的这个演讲,它详细介绍了 ListViews 和适配器: http://www.youtube.com/watch?v=wDBM6wVEO70

    【讨论】:

    • Mightier 是对的,它的重用。当我删除条件时,它会在我滚动时重置。为视频 +1。
    猜你喜欢
    • 2015-03-28
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多