39

So the following will create a ListView where the rows have their "primary" textview filled by the values array.

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
    android.R.layout.simple_list_item_2, android.R.id.text1, values);

Changing the third parameter to android.R.id.text2 sets the "secondary" textview. Is there any simple way to set both?

arjs
  • 2,835
  • 4
  • 22
  • 18

3 Answers3

122

This questions ranks high with Google but I consider the given answer to be way too complicated. As pointed out in other answers, the desired functionality can be achieved using ArrayAdapter with a very easy trick.

You can override the getView method of the ArrayAdapter:

ArrayAdapter adapter = new ArrayAdapter(context, android.R.layout.simple_list_item_2, android.R.id.text1, list) {
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    View view = super.getView(position, convertView, parent);
    TextView text1 = (TextView) view.findViewById(android.R.id.text1);
    TextView text2 = (TextView) view.findViewById(android.R.id.text2);

    text1.setText(persons.get(position).getName());
    text2.setText(persons.get(position).getAge());
    return view;
  }
};

If you didn't notice: the trick is to supply android.R.id.text1 as (principally unneccessary) parameter, otherwise the call to super will cause an exception.

Also, this solution does not make use of TwoLineListItem, which was deprecated in API 17.

Community
  • 1
  • 1
winne2
  • 2,188
  • 2
  • 17
  • 13
  • Thank this worked! The `list` variable passed to the `ArrayAdapter` is never really used though. – Fred Feb 11 '14 at 15:49
  • Yes, TwoLineListItem was deprecated but don't think that it is somehow related to SimpleCursorAdapter just because they were used together in Vipul's example. SimpleCursorAdapter is a very useful, generic ListAdapter implementation that iterates through Cursor rows, mapping the given columns to the given layout views. It should generally be preferred over writing your own ListAdapter when populating a ListView from a Cursor. Although, even if you aren't using a Cursor, it might not be out of the question to use a SimpleCursorAdapter and wrap your data in a MatrixCursor. – spaaarky21 Feb 25 '14 at 00:15
  • You are right, TwoLineListItem is not related to SimpleCursorAdapter. I included the remark simply because TwoLineListItem is used in two other answers. My solution is for simple, short lists only. More advanced solutions will e.g. make use of the ViewHolder pattern, too. – winne2 Feb 25 '14 at 11:13
  • Will this solution will slow on large lists? Is it using recycling somehow? – David Jul 04 '14 at 12:58
  • Yes, this solution will be slow for large lists, see comment from Feb 25. – winne2 Jul 17 '14 at 12:55
  • Just as an extra note, if you make the `toString` function of person return `getName()`, then the super will fill in the name part for you. – WORMSS Mar 12 '15 at 15:23
  • 1
    Thank you @winne2, this solution just ended 5 days of searching the internet. – demo.b Jan 10 '16 at 12:30
  • Just to give some more details for Newbies like me: persons needs to be declared final, – albanx Feb 05 '16 at 00:26
  • what does list refer to? Is that dummy too? – Jaydev Mar 03 '17 at 22:08
  • see first comment and https://developer.android.com/reference/android/widget/ArrayAdapter.html#ArrayAdapter(android.content.Context, int, int, java.util.List) – winne2 Mar 09 '17 at 16:15
5

hope this help you

ArrayAdapter<CustomObject> adapter = new ArrayAdapter<CustomObject> (_context, android.R.layout.simple_list_item_2, android.R.id.text1, listCustomObject) {

                                @Override
                                public View getView(int position,
                                        View convertView, ViewGroup parent) {
                                    View view = super.getView(position, convertView, parent);

                                    TextView text1 = (TextView) view.findViewById(android.R.id.text1);
                                    TextView text2 = (TextView) view.findViewById(android.R.id.text2);

                                    text1.setText(listCustomObject.get(position).getText1());

                                    text2.setText( listCustomObject.get(position).getText2() );

                                    return view;
                                }

                            };
Zeeshan
  • 1,625
  • 17
  • 25
2

can try this as well....

adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_2,values){
            @Override
            public View getView(int position, View convertView, ViewGroup parent){

               TwoLineListItem   row = (TwoLineListItem)super.getView(position, convertView, parent);

                row.getText1().setText(values.get***());
                row.getText2().setText(values.get****());

                return row;
            }
        };
    setAdapter(adapter);
Jason Robinson
  • 31,005
  • 19
  • 77
  • 131
Dheeresh Singh
  • 15,643
  • 3
  • 38
  • 36