3

I have a very simple ListView right now in a ListActivity that displays just a list of text values. Here's my current code:

public class InfoActivity extends ListActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        List<String> values = new ArrayList<String>();
        // loads up the values array here
        // ...

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, values);
        setListAdapter(adapter);
    }

My XML file for InfoActivity has nothing in it because I am using a ListActivity.

What I want to do it make custom layouts for the rows. The first 5 rows will have layoutA.xml and the second 5 rows will have layoutB.xml.

How do I do this? I'm lost on where to begin. Obviously I'm looking for the simplest code possible.

Ethan Allen
  • 14,425
  • 24
  • 101
  • 194
  • Possible duplicate: http://stackoverflow.com/questions/4777272/android-listview-with-different-layout-for-each-row – User Aug 02 '12 at 22:36

5 Answers5

2

This is a great blog post about having different layout for your list items.

handling-listviews-with-multiple-row-types

There is also the sample project so you can configure and try the example.

kyogs
  • 6,766
  • 1
  • 34
  • 50
gwvatieri
  • 5,133
  • 1
  • 29
  • 29
2

This is easy enough, you simply need to extends ArrayAdapter. My ArrayAdapter does two things differently:

  • instead of passing one ResourceId, my adapter take an array of ResourceIds
  • getView() checks the position and loads the appropriate resource

This is a trivial example. If you plan on making it more complex than the first half looks one way and the second half is different, then you should override getViewTypeCount() and getItemViewType().

Working example:

public class Example extends Activity {
    public class MyArrayAdapter<T> extends ArrayAdapter<T> {
        LayoutInflater mInflater;
        int[] mLayoutResourceIds;

        public MyArrayAdapter(Context context, int[] textViewResourceId, List<T> objects) {
            super(context, textViewResourceId[0], objects);
            mInflater = (LayoutInflater)context.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
            mLayoutResourceIds = textViewResourceId;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null && position > 2)
                convertView = mInflater.inflate(mLayoutResourceIds[1], parent, false);
            return super.getView(position, convertView, parent);
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String[] array = new String[] {"one", "two", "three", "four", "five", "six"};
        List<String> list = new ArrayList<String>();
        Collections.addAll(list, array);

        ListView listView = new ListView(this);
        listView.setAdapter(new MyArrayAdapter<String>(this, new int[] {android.R.layout.simple_list_item_1, android.R.layout.simple_list_item_single_choice}, list));
        setContentView(listView);
    }
}
Sam
  • 86,580
  • 20
  • 181
  • 179
0

I believe if you have a counter, say starting at 0, and then Inflate and reuse the first five with layoutA.xml, then when its at 5, scrap the inflated layoutA.xml with layoutB.xml. That should be simple enough to do. Of course, I am talking about this through BaseAdapter, which allows you to make an Adapter that sets each row in the ListView. I've never actually used ListActivity. But the process should be the same.

Just to add on what @lxx posted, the link I mean, it definitely helps you figure out how to accomplish what you want. Though I will say its overkill in my opinion to use those methods when you want 5 of one kind, and 5 of another. Definitely use that link as a good baseline, but just use a counter. Its simpler. In terms of memory, only re-inflate the layout when you know the counter has already put in 5 Views. That way you aren't doing it everytime.

Andy
  • 10,553
  • 21
  • 75
  • 125
0

You can try to use MergeAdapter (cwac-merge), where in one ListView you can have multiple Adapters with different layouts.

Warlock
  • 2,481
  • 4
  • 31
  • 45
0

If we need to show different type of view in list-view then its good to use getViewTypeCount() and getItemViewType() in adapter instead of toggling a view VIEW.GONE and VIEW.VISIBLE can be very expensive task inside getView() which will affect the list scroll.

Please check this one for use of getViewTypeCount() and getItemViewType() in Adapter.

Link : the-use-of-getviewtypecount

kyogs
  • 6,766
  • 1
  • 34
  • 50