6

I have to show a list with different type of Views. So I have to define a ListView with an Adapter where I have to inflate multiple views. I have gone through example given, but problem is for my list is not symmetric like the example where header is repeated each time after 4 items. So I am facing problem with reuse of items in getView()

 public View getView(int position, View convertView, ViewGroup parent) {   
    int type = getItemViewType(position);
    if (convertView == null) {
        holder = new ViewHolder();
        switch (type) {
             case TYPE_1:
             convertView = mInflater.inflate(R.layout.item1, null);
             .......
             break;

             case TYPE_2:
             convertView = mInflater.inflate(R.layout.item2, null);
             .......
             break;
        }
        convertView.setTag(holder);
    } else {
        holder = (ViewHolder)convertView.getTag();
    }
    ............
    ............
}

Now if the convertView is not null, but the item type for which it was earlier used was different, then the layout will not match with same. How this code will handle this issue?

dev_android
  • 8,698
  • 22
  • 91
  • 148
  • Don't check null condition for convertview which will always inflate the item layout. – Pankaj Apr 06 '15 at 08:00
  • you need to make 2 `ViewHolder` for item1 and item2 layouts, and in the `else` where `convertView !=null` you need to check `type` and cast to `ViewHolder1` or `ViewHolder2` ... what do you think? – Yazan Apr 06 '15 at 08:09
  • If listview items have non-symmetric layout, then you can have single listitem xml with all required elements and in getView method based on the type you can set visibility show/hide/gone. –  Apr 06 '15 at 08:14
  • Suppose 1st item of was type 1(having layout_1) and it is going to reuse in 8th element, which is of type 2(having layout_2). Now if the tag of 1st item(which is actually object of ViewHolder1) cast it to ViewHolder2, it will work? Moreover the layout will be also different. How it will work? – dev_android Apr 06 '15 at 10:50

3 Answers3

4

You can look this example adapter. getViewTypeCount method return your different type row. getItemViewType method, if position equals 0 inflate first row layout else inflate other row layout. You can customize this code example.

    import java.util.List;
    import android.app.Activity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;

    /**
     * Created by MustafaS on 9.2.2015.
     */
    public class CustomArrayAdapter extends ArrayAdapter<YourModel> {

       @Override
       public int getItemViewType(int position) {

          if (position == 0) {
             return 0;
          }
          else {
             return 1;
          }
       }

       @Override
       public int getViewTypeCount() {
          return 2;
       }

       @Override
       public View getView(int position, View convertView, ViewGroup parent) {
          int type = getItemViewType(position);
          if (type == 0) {
             if (convertView == null) {
                convertView = LayoutInflater.from(activity).inflate(R.layout.listview_first_row, parent, false);
                viewHolderFirst = new ViewHolderFirst();
                convertView.setTag(viewHolderFirst);
             }
             else {
                viewHolderFirst = (ViewHolderFirst) convertView.getTag();
             }

          }
          else {
             if (convertView == null) {
                convertView = LayoutInflater.from(activity).inflate(R.layout.listview_other_row, parent, false);
                viewHolder = new ViewHolder();

             }
             else {
                viewHolder = (ViewHolder) convertView.getTag();
             }
          }
          return convertView;
       }

       protected class ViewHolderFirst {
          private RunnableViewPager pager;
          private CircleIndicator   indicator;
       }

       protected class ViewHolder {
          private ImageView imageviewRestaurant;
          private TextView  textviewRestaurantName;
          private TextView  textviewType;
          private TextView  textviewPrice;
          private TextView  textviewDistance;
          private ImageView imageviewCall;
          private ImageView imageviewCalendar;
       }
    }
msevgi
  • 4,828
  • 2
  • 24
  • 30
  • Suppose 1st item of was type 1(having layout_1) and it is going to reuse in 8th element, which is of type 2(having layout_2). Now if the tag of 1st item(which is actually object of ViewHolderFirst) cast it to ViewHolder, it will work? Moreover the layout will be also different. How it will work? – dev_android Apr 06 '15 at 09:30
  • if your first row l a lotof different other row you should this way. But if your rows are similar, you can one row xml and one viewholder – msevgi Apr 06 '15 at 10:16
  • layout_1 and layout_2 are different. How it can be reused for type 2 which was earlier used type 1? – dev_android Apr 06 '15 at 10:53
0

You can do that by overriding the Methods getViewCount() and getItemViewType(int position)

In the first you just return the amount of different Views you have.

In the second you return a unique Identifier for each different View.

In your getView() Method you check then for the View Type and inflate the right Layout for it.

More info about that topic: Android ListView with different layouts for each row

Android ListView with different layouts for each row

Community
  • 1
  • 1
rubengees
  • 1,841
  • 2
  • 16
  • 31
0

This is what you need to use when you different types of Views inside a ListView or RecyclerView :-

getItemViewType() and getViewTypeCount()

First you need to use getViewTypeCount() and return the number of unique views you need inside your List. Then override getItemViewType() and return the View type based on the whatever condition you want your views to change on inside the ListView.

Hope it will help.

Varundroid
  • 9,135
  • 14
  • 63
  • 93