0
votes

I need to use an ArrayAdapter to populate a ListView in my Android application. In order to use the ArrayAdapter, it says

For example, if you have an array of strings you want to display in a ListView, initialize a new ArrayAdapter using a constructor to specify the layout for each string and the string array:

ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, myStringArray);

The arguments for this constructor are:

  • Your app Context
  • The layout that contains a TextView for each string in the array
  • The string array

Then simply call setAdapter() on your ListView:

ListView listView = (ListView) findViewById(R.id.listview); listView.setAdapter(adapter);

However, I do not have an array of strings, I have an array of objects that contain string values.

public class Headers {
    private String from;
    private String to;
    private String subject;

    public Headers (String from, String to, String subject){
        this.from = from;
        this.to = to;
        this.subject = subject;
    }

    public String getFrom() { return from; }
    public void setFrom(String from) { this.from = from; }

    public String getTo() { return to; }
    public void setTo(String to) { this.to = to; }

    public String getSubject() { return subject; }
    public void setSubject(String subject) { this.subject = subject; }
}

My layout does contain a TextView corresponding to values in my object.

Here is my layout with my ListView:

<LinearLayout android:orientation="vertical">
    <ListView android:id="@+id/listOfHeaders" >
</LinearLayout>

And here is the layout for each row in the ListView to be populated by the ArrayAdapter:

<LinearLayout android:orientation="horizontal">
    <TextView android:id="@+id/toTextView" />
    <TextView android:id="@+id/fromTextView" />
    <TextView android:id="@+id/subjectTextView" />
</LinearLayout>
2
so use ArrayAdapter<Headers>, and not ArrayAdapter<String> - pskink
Yes, but then I need to populate my TextViews with the strings from the Headers object, and it looks like ListView wants an array of Strings. - Brian
not really, you can override getView method and do all the mappings (it is easier if you use ArrayAdapter(Context context, int resource, int textViewResourceId) ctor) - pskink
I have no idea how to implement the intricacies of that. Which is why I posted to StackOverflow. - Brian
just override getView, call super and see what super returns, then 3 simple findViewById should be enough - pskink

2 Answers

7
votes

Using the ArrayAdapter is not enough, you will need to extend ArrayAdapter and create a custom adapter, so you can overwrite the rows creation to use your list layout. Please check this example:

public class CustomAdapter extends ArrayAdapter<Headers> {

    Context context;
    int layoutResourceId;
    ArrayList<Headers> data = null;

    public CustomAdapter(Context context, int resource, List<Headers> objects) {
        super(context, resource, objects);
        this.layoutResourceId = resource;
        this.context = context;
        this.data = (ArrayList) objects;
    }

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

        if(row == null)
        {
            LayoutInflater inflater = ((Activity)context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);

            holder = new HeaderHolder();
            holder.from = (TextView) row.findViewById(R.id.fromTextView);
            holder.to = (TextView)row.findViewById(R.id.toTextView);
            holder.subject = (TextView)row.findViewById(R.id.subjectTextView);

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

        Headers item = data.get(position);
        holder.from.setText(item.getFrom());
        holder.to.setText(item.getTo());
        holder.subject.setText(item.getSubject());

        return row;
    }

    private class HeaderHolder {
        public TextView from;
        public TextView to;
        public TextView subject;

    }
}

For the Activity, on the onCreate method:

ListView list = (ListView) findViewById(R.id.listView);
ArrayList<Headers> data = new ArrayList<Headers>();
data.add(new Headers("from", "to", "subject"));

ArrayAdapter adapter = new CustomAdapter(this, R.layout.list, data);
list.setAdapter(adapter); 

You can see that the CustomAdapter is using HeaderHolder as part of the ViewHolder pattern so the list management is efficient.

0
votes

For your kind of info, you can actually do that by overriding getView() method. Basically you have to provide custom Layout for your ListView item and that you have to inflate in you getView() method. For more info you can link to this one: http://www.ezzylearning.com/tutorial/customizing-android-listview-items-with-custom-arrayadapter