Advanced ListView: populating a list with images and text

Posted by Marco Dinacci on 0 comments

The Android documentation says that the ListView widget is easy to use. It is true if you just want to display a simple list of strings but as soon as you want to customize your list things become more complicated.

The following is a tutorial on how to write a ListView that displays a static list of images and strings, similar to the settings list on your phone.

For the impatients, here's the Eclipse project code and a picture of the final result: Advanced ListView demo screenshot

Let's start with the Activity code. First of all, we extends from ListActivity instead of Activity so we can easily supply our custom adapter:

public class AdvancedListViewActivity extends ListActivity {

    public void onCreate(Bundle savedInstanceState) {
        Context ctx = getApplicationContext();
    Resources res = ctx.getResources();

    String[] options = res.getStringArray(R.array.country_names);
    TypedArray icons = res.obtainTypedArray(R.array.country_icons);
    setListAdapter(new ImageAndTextAdapter(ctx, R.layout.main_list_item, options, icons));

In the onCreate we also create an array of strings, which contains the country names, and a TypedArray, which will contain our Drawable flags.

The arrays are created from an XML file, here's the content of the countries.xml file.

<?xml version="1.0" encoding="utf-8"?>
    <string-array name="country_names">
    <array name="country_icons">

Now we're ready to create the adapter. The official documentation for Adapter says:
An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.

There are already various subclasses of Adapter, we're going to extend on ArrayAdapter which is a concrete BaseAdapter that is backed by an array of arbitrary objects.

public class ImageAndTextAdapter extends ArrayAdapter<String> {

    private LayoutInflater mInflater;
    private String[] mStrings;
    private TypedArray mIcons;
    private int mViewResourceId;
    public ImageAndTextAdapter(Context ctx, int viewResourceId,
            String[] strings, TypedArray icons) {
        super(ctx, viewResourceId, strings);
        mInflater = (LayoutInflater)ctx.getSystemService(
        mStrings = strings;
        mIcons = icons;
        mViewResourceId = viewResourceId;

    public int getCount() {
        return mStrings.length;

    public String getItem(int position) {
        return mStrings[position];

    public long getItemId(int position) {
        return position;

    public View getView(int position, View convertView, ViewGroup parent) {
        convertView = mInflater.inflate(mViewResourceId, null);
        ImageView iv = (ImageView)convertView.findViewById(;

        TextView tv = (TextView)convertView.findViewById(;
        return convertView;

The constructor accepts a Context, the id of the layout that will be used for every row (more on this soon), an array of strings (the country names) and a TypedArray (our flags).

The getView method is where we build a row for the list. We first use a LayoutInflater to create a View from XML, then we retrieve the country flag as a Drawable and the country name as a String and we use them to populate the ImageView and TextView that we've declared in the layout.

The layout for the list rows is the following:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="">
        android:textSize="16dp" >

As a reference, this is the content of the main layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""
<ListView android:id="@android:id/list" 

Note that the ListView ID must be exactly

or you'll get a RuntimeException.

That's it, you can download the Eclipse project code or post a comment if you have any question.