Android: getView() called twice in custom adapter

jul picture jul · Mar 8, 2011 · Viewed 17.6k times · Source

I'm setting a custom SimpleCursorAdapter to a ListView. For some reason FriendAdapter's getView() is called twice for every item in the DB. After some investigation (I have no wrap_content in my contact_list.xml), I can still not figure out why.

What could be the reasons? Anybody can help?

Thanks

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>

Answer

Peter Knego picture Peter Knego · Mar 8, 2011

This is normal and can happen when you have a listview with height=wrap_content (among others):

Look at the last post: http://groups.google.com/group/android-developers/browse_thread/thread/4c4aedde22fe4594