Logo Icon Logo
A Crowd-sourced Cookbook on Writing Great Android® Apps
GitHub logo Twitter logo OReilly Book Cover Art

Creating an Advanced ListView with Images and Text

In Chapter: Other GUI Elements: Lists and Views
Author: Marco Dinacci ('lunkwill')
Published? true
FormatLanguage: WikiFormat


You want to write a ListView that shows an image next to a string.


We're going to create an Activity that extends from ListActivity, prepare the XML resource files and at last create a custom view adapter to load the resources onto the view.


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.

This recipe shows you how to write a ListView that displays a static list of images and strings, similar to the settings list on your phone.

Here's a picture of the final result:

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:

<para>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.</para>

There are several 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 0;

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

		TextView tv = (TextView)convertView.findViewById(R.id.option_text);
		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="http://schemas.android.com/apk/res/android">
	    android:textSize="16dp" >

And this is the content of the main layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<ListView android:id="@android:id/list" 

Note that the ListView ID must be exactly @android:id/listor you'll get a RuntimeException.


The source code for this project is in the Android Cookbook repository, http://github.com/IanDarwin/Android-Cookbook-Examples/tree/master/ListViewAdvanced.


If you found this recipe useful, why not buy the book and have the whole collection always at hand?"