views:

111

answers:

1

I'm having problems with some BaseAdapter code that I adapted from a book. I've been using variations of this code all over the place in my application, but only just realized when scrolling a long list the items in the ListView become jumbled and not all of the elements are displayed.

It's very hard to describe the exact behavior, but it's easy to see if you take a sorted list of 50 items and start scrolling up and down.

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

}
A: 

You are only putting data in the TextView widgets when they are first created. You need to move these four lines:

        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());

to be after the if/else block and before the method return, so you update the TextView widgets whether you are recycling the row or creating a fresh one.

CommonsWare
Oh, I see. So the ListView only contains at most the number of Views necessary to fill the screen?
Mr. Ambiguous
@Mr. Ambiguous: More or less. It may cache a couple to be able to react quickly to scroll requests. However, in a `ListView` with UI space for 10 rows and an `Adapter` of 1,000 rows, the number of `Views` will be far closer to 10 than 1,000. Probably like 12 or 14. That's the point of row recycling with `convertView`, so Android does not have to create (and later GC) a whole mess of row widgets.
CommonsWare