1

Context
I want to have a list with 3 significantly different layouts for list items so I make my adapter that based on type of item to display creates appropriate view.
e.g. i want to list some images, texts and numbers, each with some title. I know that in
public View getView(int position, View convertView, ViewGroup parent)
the convertView stands for reusing no longer visible listItems views.

Question
How can I choose the convertView or how can i control what i get in there?

The problem comes with different listItems views, assume I have my list starting with an image listItem, then comes a lot of text listItems and number listItems and 100 listItems later comes second image. I assume that while scrolling down the list, (in getView(...) calls) the first convertView that is not null is the one with image, and since i need a view to display text listItem or number listItem I cannot use it. Then i guess that in every next getView(...) call the convertView is that same image listItem as in previous calls because i didn't use it before.

The unused text listItems and number listItems stuck up and when scrolling the list I need to keep creating new views, this is what i want to prevent.

mrtpk
  • 1,398
  • 4
  • 18
  • 38

2 Answers2

5

Try this,

@Override
public View getView(final int position, View convertview, ViewGroup parent) {
    // TODO Auto-generated method stub
    final ViewHolder mHolder;
    if (convertview == null) {
        convertview = mInflater.inflate(R.layout.list_item, null);
        mHolder = new ViewHolder();
        mHolder.username_Txt = (TextView) convertview
                .findViewById(R.id.username_Txt);

        convertview.setTag(mHolder);
    } else {
        mHolder = (ViewHolder) convertview.getTag();
    }

    try {
        mHolder.username_Txt.setText("your value");


    } catch (Exception e) {
        // TODO: handle exception
    }

    return convertview;
}
private class ViewHolder {

    private TextView username_Txt;

}
Murali Ganesan
  • 2,925
  • 4
  • 20
  • 31
3

You need to let the adapter's view recycler know that there is more than one layout and how to distinguish between the two for each row. Simply override these methods:

Here i have said for 2 different layouts. If you have more use an enum to distinguish them.

@Override
public int getItemViewType(int position) {
    // Define a way to determine which layout to use, here it's just evens and odds.
    return position % 2;
}

@Override
public int getViewTypeCount() {
    return 2; // Count of different layouts (Change according to your requirment)
}

Incorporate getItemViewType() inside getView(), like this:

if (convertView == null) {
    // You can move this line into your constructor, the inflater service won't change.
    mInflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
    if(getItemViewType(position) == 0)
        convertView = mInflater.inflate(R.layout.listview_item_product_1, parent,false);
    else
        convertView = mInflater.inflate(R.layout.listview_item_product_2,parent,false);
    // etc, etc...

Watch Android's Romain Guy discuss the view recycler at Google Talks.

Suhail Mehta
  • 5,514
  • 2
  • 23
  • 37