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

ListView with Icons/images

Author: w2davids
Published? false
FormatLanguage: WikiFormat


You want to display data in a ListView with an icon image and some text for each ListView row.


This recipe demonstrate how to load data from a XML file, and view the results in a ListView with each row item having an image/icon.

Firstly, the XML resource file must be place in a raw/ directory beneath the res/ folder. In the countries.xml file, all the data is enclosed in the countries and countries tag with each element being enclosed in a country country tag with attributes indicating the name, abbreviation and region of the respective country.

A Java class Country.java is used to model each ListView row item. XML parsing in Android is accomplished by using the built-in SAX parser. In parsing the countries.xml file, the parser CountryParser.java is used to obtain the country names, abbreviations, and regions using the node values extracted from countries.xml. A new Country java object for each XML node which includes the filename of the country image to use.

The above explanation covers the data input from an XML-based file. Now moving to the meat and bones so to speak.

CountryArrayAdapter extends the ArrayAdapter class in which a Context and a list of Country objects are supplied as parameters. The most important function is the getView() function. The getView() function allows the ListView row elements to be altered, in this case the icon image is inserted to the left, and the country name and abbreviation to the right of it.

A simple XML-based View layer listview.xml is created, in which a reference to a countryLV is declared in a ListView element.

For data-binding, a Main.java Android activity is created in which the various elements describe above is brought together. The function setContentView(R.layout.listview) loads the XML view file listview.xml, and extracts a reference to the countryLV ListView holder. The XML parser, called CountryParser loads the data into a Java List containing Country objects.

The custom CountryArrayAdapter is used to override the ListView display so that each row contains the country icon, country name and abbreviation.

Re-wrote this example: 1. xml for listview of countries 2. xml for each row item in listview with place holders for image, country_name, country_abbrev 3. Customized ArrayAdapter for using Country object. 4. Acessing image files in the assets/ directory using: // Set country icon usign File path String imgFilePath = ASSETS_DIR + country.resourceId; try { Bitmap bitmap = BitmapFactory.decodeStream(this.context.getResources().getAssets() .open(imgFilePath)); countryIcon.setImageBitmap(bitmap); } catch (IOException e) { e.printStackTrace(); }


Create a custom ArrayAdapter for modifying visual display of list items.

File: listview.xml - The XML-layout file

<?xml version="1.0" encoding="utf-8"?>

File: country_listitem.xml

<?xml version="1.0" encoding="utf-8"?>

		android:layout_height="wrap_content" />

		android:text="Country Name"
		android:layout_height="wrap_content" />
		android:text="Country Abbrev"
		android:layout_height="wrap_content" />


File: countries.xml

<?xml version="1.0" encoding="utf-8"?>
		<country name="Australia" abbreviation="au" region="Asia" />
		<country name="Austria" abbreviation="at" region="Europe" />
		<country name="Belgium" abbreviation="be" region="Europe" />
		<country name="Brazil" abbreviation="br" region="S. America" />
		<country name="Canada" abbreviation="ca" region="N. America" />
		<country name="China" abbreviation="cn" region="Asia" />
		<country name="Denmark" abbreviation="dk" region="Europe" />
		<country name="France" abbreviation="fr" region="Europe" />
		<country name="Germany" abbreviation="de" region="Europe" />
		<country name="Hong Kong" abbreviation="hk" region="Asia" />
		<country name="India" abbreviation="in" region="Asia" />
		<country name="Indonesia" abbreviation="id" region="Asia" />
		<country name="Italy" abbreviation="it" region="Europe" />
		<country name="Korea" abbreviation="kr" region="Asia" />
		<country name="Netherlands" abbreviation="nl" region="Europe" />
		<country name="Norway" abbreviation="no" region="Europe" />
		<country name="Portugal" abbreviation="pt" region="Europe" />
		<country name="Singapore" abbreviation="sg" region="Asia" />
		<country name="Spain" abbreviation="es" region="Europe" />
		<country name="Sweden" abbreviation="se" region="Europe" />
		<country name="Switzerland" abbreviation="ch" region="Europe" />
		<country name="Taiwan" abbreviation="tw" region="Asia" />
		<country name="United Kingdom" abbreviation="uk" region="Europe" />
		<country name="United States" abbreviation="us" region="N. America" />

File: Main.java


import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class Main extends Activity {

	private List<Country> countryList= new ArrayList<Country>();
	/** Called when the activity is first created. */
	public void onCreate(Bundle savedInstanceState) {
		// Set the View layer

		// Create Parser for raw/countries.xml
		CountryParser countryParser = new CountryParser();
		InputStream inputStream = getResources().openRawResource(
		// Parse the inputstream

		// Get Countries
		List<Country> countryList = countryParser.getList();
		// Create a customized ArrayAdapter
		CountryArrayAdapter adapter = new CountryArrayAdapter(
				getApplicationContext(), R.layout.country_listitem, countryList);
		// Get reference to ListView holder
		ListView lv = (ListView) this.findViewById(R.id.countryLV);
		// Set the ListView adapter

File: Country.java

public class Country
		public String name;
		public String abbreviation;
		public String region;
		public String resourceId;

		public Country()
				// TODO Auto-generated constructor stub

		public Country(String name, String abbreviation, String region, String resourceFilePath)
				this.name = name;
				this.abbreviation = abbreviation;
				this.region= region;
				this.resourceId = resourceFilePath;

		public String toString()
				return this.name;

File: CountryParser.java

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import android.util.Log;

public class CountryParser {

	private static final String tag = "CountryParser";
	private static final String FILE_EXTENSION= ".png";
	private DocumentBuilderFactory factory;
	private DocumentBuilder builder;
	private final List<Country> list;

	public CountryParser() {
		this.list = new ArrayList<Country>();

	private String getNodeValue(NamedNodeMap map, String key) {
		String nodeValue = null;
		Node node = map.getNamedItem(key);
		if (node != null) {
			nodeValue = node.getNodeValue();
		return nodeValue;

	public List<Country> getList() {
		return this.list;

	 * Parse XML file containing body part X/Y/Description
	 * @param inStream
	public void parse(InputStream inStream) {
		try {
			// TODO: after we must do a cache of this XML!!!!
			this.factory = DocumentBuilderFactory.newInstance();
			this.builder = this.factory.newDocumentBuilder();
			Document doc = this.builder.parse(inStream, null);


			NodeList countryList = doc.getElementsByTagName("country");
			final int length = countryList.getLength();

			for (int i = 0; i < length; i++) {
				final NamedNodeMap attr = countryList.item(i).getAttributes();
				final String countryName = getNodeValue(attr, "name");
				final String countryAbbr = getNodeValue(attr, "abbreviation");
				final String countryRegion = getNodeValue(attr, "region");

				// Construct Country object
				Country country = new Country(countryName, countryAbbr,
						countryRegion, countryAbbr + FILE_EXTENSION);
				// Add to list
				Log.d(tag, country.toString());
		} catch (SAXException e) {
		} catch (IOException e) {
		} catch (ParserConfigurationException e) {

File: CountryArrayAdapter.java

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class CountryArrayAdapter extends ArrayAdapter<Country> {

	private static final String tag = "CountryArrayAdapter";
	private static final String ASSETS_DIR = "images/";
	private Context context;

	private ImageView countryIcon;
	private TextView countryName;
	private TextView countryAbbrev;
	private List<Country> countries = new ArrayList<Country>();

	public CountryArrayAdapter(Context context, int textViewResourceId,
			List<Country> objects) {
		super(context, textViewResourceId, objects);
		this.context = context;
		this.countries = objects;

	public int getCount() {
		return this.countries.size();

	public Country getItem(int index) {
		return this.countries.get(index);

	public View getView(int position, View convertView, ViewGroup parent) {
		View row = convertView;
		if (row == null) {
			Log.d(tag, "Starting XML Row Inflation ... ");
			LayoutInflater inflater = (LayoutInflater) this.getContext()
			row = inflater.inflate(R.layout.country_listitem, parent, false);
			Log.d(tag, "Successfully completed XML Row Inflation!");

		// Get item
		Country country = getItem(position);
		// Get reference to ImageView 
		countryIcon = (ImageView) row.findViewById(R.id.country_icon);
		// Get reference to TextView - country_name
		countryName = (TextView) row.findViewById(R.id.country_name);
		// Get reference to TextView - country_abbrev
		countryAbbrev = (TextView) row.findViewById(R.id.country_abbrev);

		//Set country name
		// Set country icon usign File path
		String imgFilePath = ASSETS_DIR + country.resourceId;
		try {
			Bitmap bitmap = BitmapFactory.decodeStream(this.context.getResources().getAssets()
		} catch (IOException e) {
		// Set country abbreviation
		return row;

The result should look like this:


The source code for this project can be downloaded from http://www.filefactory.com/file/b4a5548/n/IconizedListView.zip.