user4790312
user4790312

Reputation:

Android multi row items in list view

i'm trying to change rows in list view by check all ArrayList item in getView. if item.getSend_status() is -1 convertView must be inflate layout_message_content_list_rtl otherwise layout_message_content_list_ltr.

in my getView i wrote that, but after scroll listview else dont work and for all of items only layout_message_content_list_ltr inflated, for example if i have two item in ArrayList as an this structure:

public class RowItems{
    int send_status;
    String title;
}

in item one send_status is -1 and second item is 1, my list view must be have different item, but thats not working correctly and i have only on inflate in listview

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder   mViewHolder;
    MessagesList item = getItem(position);

    if (convertView == null) {
        if (item.getSend_status() == -1) {
            convertView = inflater.inflate(R.layout.layout_message_content_list_rtl, null);
        } else{
            convertView = inflater.inflate(R.layout.layout_message_content_list_ltr, null);
        }
        mViewHolder = new ViewHolder(convertView);
        convertView.setTag(mViewHolder);
    } else {
        mViewHolder = (ViewHolder) convertView.getTag();
    }

    mViewHolder.fillItems(this, item, position);

    return convertView;
}

Logcat:

this result is for Log.e("Send_status: ",item.getSend_status()+""); into fillItems:

E/Send_status:﹕ -1
E/Send_status:﹕ 1
E/Send_status:﹕ 1

Upvotes: 1

Views: 809

Answers (1)

Awanish Raj
Awanish Raj

Reputation: 2009

This won't work and is the expected behaviour. We should begin by understanding what convertView stands for!

To re-use views, android recycles an already inflated view of a out-of-viewport position to your getView() method with the name convertView. For homogeneous lists(single type of layout), this works out perfectly, because the convertView will have the same layout as your new view. So android says, "Hey, the view is already inflated, take it! Just update the items in it with the data for that position!."

Now what if you have two types of layouts. Fear not, this is accommodated in the Adapter's architecture!

You need to override following two methods in your adapter's code:

@Override
public int getViewTypeCount() {
    return 2; //Number of different layouts in the list. "rtl" and "ltr" = 2 in your case.
}

@Override
public int getItemViewType(int position) {
    MessagesList item = getItem(position);
    if (item.getSend_status() == -1) {
        return 0; // for rtl
    }
    else {
        return 1; // for ltr
    }
    //The return value must be less than the view type count
}

Now, in your getView() method, do this:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder   mViewHolder;
    MessagesList item = getItem(position);
    View newView = convertView;

    if (newView == null) {
        if (getItemViewType(position)==0) {
            newView = inflater.inflate(R.layout.layout_message_content_list_rtl, parent, false);
        } else {
            newView = inflater.inflate(R.layout.layout_message_content_list_ltr, parent, false);
        }
        mViewHolder = new ViewHolder(newView);
        newView.setTag(mViewHolder);
    } else {
        mViewHolder = (ViewHolder) newView.getTag();
    }

    mViewHolder.fillItems(this, item, position);

    return newView;
}

Upvotes: 1

Related Questions