Android: getView () дважды вызывается в пользовательском адаптере

Я устанавливаю пользовательский SimpleCursorAdapter в ListView. По какой-то причине getView () FriendAdapter вызывается дважды для каждого элемента в БД. После некоторого расследования (у меня нет wrap_content в моем contact_list.xml), я все еще не могу понять, почему.

Каковы могут быть причины? Кто-нибудь может помочь?

благодаря

ContactSelection.java

public class ContactSelection extends ListActivity { private WhipemDBAdapter mDbHelper; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mDbHelper = new WhipemDBAdapter(this); mDbHelper.open(); setContentView(R.layout.contact_list); Cursor c = mDbHelper.fetchAllFriends(); startManagingCursor(c); String[] from = new String[] {}; int[] to = new int[] {}; setListAdapter(new FriendAdapter(this, R.layout.contact_row, c, from, to)); getListView().setItemsCanFocus(false); getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); } @Override protected void onResume() { super.onResume(); mDbHelper.open(); } @Override protected void onPause() { super.onPause(); mDbHelper.close(); } } 

FriendAdapter.java

 public class FriendAdapter extends SimpleCursorAdapter implements OnClickListener { private Context mContext; private int mLayout; private Cursor mCursor; private int mNameIndex; private int mIdIndex; private LayoutInflater mLayoutInflater; private final ImageDownloader imageDownloader = new ImageDownloader(); private final class ViewHolder { public TextView name; public ImageView image; public CheckBox checkBox; } public FriendAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { super(context, layout, c, from, to); this.mContext = context; this.mLayout = layout; this.mCursor = c; this.mNameIndex = mCursor.getColumnIndex(WhipemDBAdapter.KEY_NAME); this.mIdIndex = mCursor.getColumnIndex(WhipemDBAdapter.KEY_FB_ID); this.mLayoutInflater = LayoutInflater.from(context); } public View getView(int position, View convertView, ViewGroup parent) { if (mCursor.moveToPosition(position)) { ViewHolder viewHolder; if (convertView == null) { convertView = mLayoutInflater.inflate(mLayout, null); viewHolder = new ViewHolder(); viewHolder.name = (TextView) convertView.findViewById(R.id.contact_name); viewHolder.image = (ImageView) convertView.findViewById(R.id.contact_pic); viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.checkbox); viewHolder.checkBox.setOnClickListener(this); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } String name = mCursor.getString(mNameIndex); String fb_id = mCursor.getString(mIdIndex); boolean isChecked = ((GlobalVars) mContext.getApplicationContext()).isFriendSelected(fb_id); viewHolder.name.setText(name); imageDownloader.download("http://graph.facebook.com/"+fb_id+"/picture", viewHolder.image); viewHolder.checkBox.setTag(fb_id); viewHolder.checkBox.setChecked(isChecked); } return convertView; } @Override public void onClick(View v) { CheckBox cBox = (CheckBox) v; String fb_id = (String) cBox.getTag(); if (cBox.isChecked()) { if (!((GlobalVars) mContext.getApplicationContext()).isFriendSelected(fb_id)) ((GlobalVars) mContext.getApplicationContext()).addSelectedFriend(fb_id); } else { if (((GlobalVars) mContext.getApplicationContext()).isFriendSelected(fb_id)) ((GlobalVars) mContext.getApplicationContext()).removeSelectedFriend(fb_id); } } } 

contact_row.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:id="@+id/contact_pic" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/contact_name" android:textSize="10sp" android:singleLine="true" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <CheckBox android:id="@+id/checkbox" android:layout_alignParentRight="true" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> 

contact_list.xml

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ListView android:id="@+id/android:list" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <TextView android:id="@+id/android:empty" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="No items"/> </LinearLayout> 

Solutions Collecting From Web of "Android: getView () дважды вызывается в пользовательском адаптере"

Это нормально и может произойти, если у вас есть listview с height=wrap_content (среди прочих):

Посмотрите на последнее сообщение: http://groups.google.com/group/android-developers/browse_thread/thread/4c4aedde22fe4594

Я использовал это. getView запускается дважды, но если вы проверите, является ли convertView null , код внутри будет выполняться один раз.

 public View getView(int position, View convertView, ViewGroup parent) { View superView = super.getView(position, convertView, parent); if (convertView == null) { // Customize superView here } return superView; } 

Чтобы getView получил вызов только один раз для каждой строки, вам нужно вызвать super.getView, а затем изменить возвращаемое представление. Это что-то вроде этого

 public View getView(int position, View convertView, ViewGroup parent) { View superView = super.getView(position, convertView, parent); if (mCursor.moveToPosition(position)) { // Customize superView here } return superView; } 

Для меня кажется, что представление создается дважды в том же методе. Один в «if (convertView == null)», а другой «else». Если бы я ничего не делал в один раз из операторов if, то он создается только один раз. Похоже, что этот метод называется только один раз.