jul
jul

Reputation: 37474

Recycling ListView rows with different row layouts

I have a ListView adapter which is set with different layouts according to the type of the row item.

If I recycle my rows using a holder, as shown in the code below, I think I'll get some errors because for a recycled row I'll get the layout of the latest non-recycled row, which might not be of the same type.

Should I avoid recycling the rows in that case? What other options do I have?

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    MyHolder holder = null;

    int type = getItemViewType(position);

    if(row == null)
    {           
        holder = new MyHolder();

        LayoutInflater inflater = ((Activity)mContext).getLayoutInflater();

        if(type == TYPE_1){
            row = inflater.inflate(R.layout.layout_type_1, parent, false);
        }
        else if(type == TYPE_2){
            row = inflater.inflate(R.layout.layout_type_2, parent, false);
        }               
        else {
            row = inflater.inflate(R.layout.layout_type_3, parent, false);
        }

        row.setTag(holder);
    }
    else
    {
        holder = (MyHolder)row.getTag();
    }

    /* ... */
}

Upvotes: 2

Views: 1604

Answers (2)

user
user

Reputation: 87064

If I recycle my rows using a holder, as shown in the code below, I think I'll get some errors because for a recycled row I'll get the layout of the latest non-recycled row, which might not be of the same type.

If you are referring to the row == null check, then there is no problem as the ListView will give you the right convertView according to the getItemViewType() method.

If you are referring to the MyHolder class this again is not a problem because the holder is set as the tag for the row view and if the ListView gives you the right recycled row view then the holder tag will also have the proper fields initialized in it for that type of row. And, as you should handle the MyHolder according to the row type this isn't a problem as you'll access the initialized fields. Your MyHolder class should have references for all the views that your three type of rows expose so you have where to put them.

So keep the recycling mechanism.

Upvotes: 2

Streets Of Boston
Streets Of Boston

Reputation: 12596

Always recycle rows! Your implementation of getItemViewType (and getViewTypeCount) instructs the ListView when to recycle what types of views so that they won't get mixed up.

Your code snippet looks good. So, it all should work. The only slightly odd part is the if(type == TYPE_3). Did you mean if(type == TYPE_2)?

The question is: Do you have problem/exception in your code right now?

Upvotes: 5

Related Questions