BaseAdapter导致ListView在滚动时出现乱序

我遇到了一些我从一本书改编的BaseAdapter代码的问题。 我一直在我的应用程序遍地使用这个代码的变体,但只有当滚动一个长列表ListView中的项目变得混乱,并不是所有的元素都显示。

描述确切的行为是非常困难的,但是很容易看出你是否对50个项目进行sorting,并开始上下滚动。

class ContactAdapter extends BaseAdapter { ArrayList<Contact> mContacts; public ContactAdapter(ArrayList<Contact> contacts) { mContacts = contacts; } @Override public int getCount() { return mContacts.size(); } @Override public Object getItem(int position) { return mContacts.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view; if(convertView == null){ LayoutInflater li = getLayoutInflater(); view = li.inflate(R.layout.groups_item, null); TextView label = (TextView)view.findViewById(R.id.groups_item_title); label.setText(mContacts.get(position).getName()); label = (TextView)view.findViewById(R.id.groups_item_subtitle); label.setText(mContacts.get(position).getNumber()); } else { view = convertView; } return view; } } 

Solutions Collecting From Web of "BaseAdapter导致ListView在滚动时出现乱序"

在第一次创build时,您只将数据放入TextView小部件中。 您需要移动这四行:

  TextView label = (TextView)view.findViewById(R.id.groups_item_title); label.setText(mContacts.get(position).getName()); label = (TextView)view.findViewById(R.id.groups_item_subtitle); label.setText(mContacts.get(position).getNumber()); 

if / else块之后和方法返回之前,所以您更新TextView小部件,无论您正在回收行还是创build新行。

为了进一步澄清CommonsWare的答案,下面是一些更多的信息:

li.inflate操作(这里需要parsingXML中的行布局并创build相应的View对象)由if(convertView == null)语句包装以提高效率,所以同一对象的通货膨胀不会发生它每次都会一次又一次地出现在视图中。

然而,getView方法的其他部分用于设置其他参数,因此不应该包含在if(convertView == null){} … else {}语句中。

在这个方法的很多常见的实现中,一些textView标签,ImageView或者ImageButton元素需要使用findViewById以及.setText或者.setImageBitmap操作来从列表[position]中填充值。 这些操作必须在通过通货膨胀从头开始创build一个视图, 获得一个现有的视图,如果不是空的(例如刷新)。

https://stackoverflow.com/a/3874639/978329中显示了另一个适用于ListView ArrayAdapter的解决scheme。