Android: getView() called twice in custom adapter

十年热恋 提交于 2019-12-04 16:51:16

问题


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>

回答1:


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




回答2:


I used this. The getView runs twice, but if you check if convertView is null, the code inside will be run once.

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

    }
    return superView;
}



回答3:


For me it seems like the view is created twice in the same method. One in "if(convertView==null)" and the other "else". If I did nothing in once of the if statements then it is only created once. It seems like the method itself is only called once though.




回答4:


In order to getView get call only once for each row, you need to call super.getView and then change the returned view. It's something like this

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;
}


来源:https://stackoverflow.com/questions/5230155/android-getview-called-twice-in-custom-adapter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!