This tutorial follows the old way of customizing the ListView using a third party library.
Consider reading the more efficient solution which uses Volley library to achieve the same. Android Custom ListView with Image and Text using Volley

This is a tutorial about customizing listview with an image and text. For this tutorial I am using some of the classes from this link. In this tutorial I explained how to load images from remote url and update into listview. Also explained how to design listview with your custom styles and colors instead of using default listview style.

Download Code

The Sample XML

For this tutorial I am using following sample XML which has some data and a thumbnail image url. You can get this XML by accessing https://api.androidhive.info/music/music.xml

<?xml version="1.0" encoding="UTF-8"?>
<music>
    <song>
        <id>1</id>
        <title>Someone Like You</title>
        <artist>Adele</artist>
        <duration>4:47</duration>
	    <plays>1662</plays>
	    <thumb_url>https://api.androidhive.info/music/images/adele.png</thumb_url>
    </song>
	<song>
        <id>2</id>
        <title>Space Bound</title>
        <artist>Eminem</artist>
        <duration>4:38</duration>
	    <plays>1900</plays>
	    <thumb_url>https://api.androidhive.info/music/images/eminem.png</thumb_url>
    </song>
       .
       .
       .
       .
</music>

Before going further make sure that you covered Android XML Parsing Tutorial and Android ListView Tutorial before

Creating New Project

1. Create new project in your Eclipse IDE and fill all the details. File ⇒ New Project
2. If you notice the screen shots I designed listview with gradient background. To define gradient style create three new XML files under drawable folder and name them as gradient_bg.xml, list_selector.xml and gradient_bg_hover.xml and fill with following code. Also the thumbnail image has white background, for this I used image_bg.xml
Right Click and drawable-hdpi ⇒ New ⇒ Android XML File

gradient_bg.xml – Default Background Gradient Style

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
  <gradient
      android:startColor="#f1f1f2"
      android:centerColor="#e7e7e8"
      android:endColor="#cfcfcf"
      android:angle="270" />
</shape>

gradient_bg_hover.xml – Gradient Style for on hover state

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
  <gradient
      android:startColor="#18d7e5"
      android:centerColor="#16cedb"
      android:endColor="#09adb9"
      android:angle="270" />
</shape>

list_selector.xml – Actual liststyle which combines the above two styles

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
	<item
	 android:state_selected="false"
		android:state_pressed="false"
		android:drawable="@drawable/gradient_bg" />

	<item android:state_pressed="true"
		android:drawable="@drawable/gradient_bg_hover" />

	<item android:state_selected="true"
	 android:state_pressed="false"
		android:drawable="@drawable/gradient_bg_hover" />
</selector>

image_bg.xml – is for white border around the image in listview

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
      <shape
        android:shape="rectangle">
            <stroke android:width="1dp" android:color="#dbdbdc" />
            <solid android:color="#FFFFFF" />
        </shape>
   </item>
</layer-list>

3. Now open your main.xml file and define a listview in it.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <ListView
        android:id="@+id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:divider="#b5b5b5"
        android:dividerHeight="1dp"
        android:listSelector="@drawable/list_selector" />

</LinearLayout>

4. Next step is to design single listrow. Create a new XML file under layout folder and name it as list_row.xml.
Right Click ⇒ New ⇒ Android XML File

In this tutorial I custom designed a listview which contains an image on leftside, time and arrow at the right end and a title in middle. I used RelativeLayout as parent node and placed all the remaining items using relative positioning properties. Check the following image

android custom listview

list_row.xml – Single ListRow Layout

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/list_selector"
    android:orientation="horizontal"
    android:padding="5dip" >

	<!--  ListRow Left sied Thumbnail image -->
	<LinearLayout android:id="@+id/thumbnail"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:padding="3dip"
        android:layout_alignParentLeft="true"
        android:background="@drawable/image_bg"
	    android:layout_marginRight="5dip">

		<ImageView
			android:id="@+id/list_image"
	        android:layout_width="50dip"
	        android:layout_height="50dip"
	        android:src="@drawable/rihanna"/>

	</LinearLayout>

	<!-- Title Of Song-->
    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/thumbnail"
        android:layout_toRightOf="@+id/thumbnail"
        android:text="Rihanna Love the way lie"
        android:textColor="#040404"
        android:typeface="sans"
        android:textSize="15dip"
        android:textStyle="bold"/>

	<!-- Artist Name -->
    <TextView
        android:id="@+id/artist"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/title"
        android:textColor="#343434"
        android:textSize="10dip"
        android:layout_marginTop="1dip"
        android:layout_toRightOf="@+id/thumbnail"
        android:text="Just gona stand there and ..." />

	<!-- Rightend Duration -->
    <TextView
        android:id="@+id/duration"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignTop="@id/title"
        android:gravity="right"
        android:text="5:45"
        android:layout_marginRight="5dip"
        android:textSize="10dip"
        android:textColor="#10bcc9"
        android:textStyle="bold"/>

     <!-- Rightend Arrow -->
     <ImageView android:layout_width="wrap_content"
     	android:layout_height="wrap_content"
     	android:src="@drawable/arrow"
     	android:layout_alignParentRight="true"
     	android:layout_centerVertical="true"/>

</RelativeLayout>

The above XML will provide you output like below

android listview selected state

5. Until now we completed designing part of the listview. Next step is to parse the xml and update the data into listview. Create a new java class file in your src folder. Right Click on src ⇒ New ⇒ Class and name it as LazyAdapter.java

package com.example.androidhive;

import java.util.ArrayList;
import java.util.HashMap;

import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class LazyAdapter extends BaseAdapter {

    private Activity activity;
    private ArrayList&lt;HashMap&lt;String, String&gt;&gt; data;
    private static LayoutInflater inflater=null;
    public ImageLoader imageLoader; 

    public LazyAdapter(Activity a, ArrayList&lt;HashMap&lt;String, String&gt;&gt; d) {
        activity = a;
        data=d;
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        imageLoader=new ImageLoader(activity.getApplicationContext());
    }

    public int getCount() {
        return data.size();
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View vi=convertView;
        if(convertView==null)
            vi = inflater.inflate(R.layout.list_row, null);

        TextView title = (TextView)vi.findViewById(R.id.title); // title
        TextView artist = (TextView)vi.findViewById(R.id.artist); // artist name
        TextView duration = (TextView)vi.findViewById(R.id.duration); // duration
        ImageView thumb_image=(ImageView)vi.findViewById(R.id.list_image); // thumb image

        HashMap&lt;String, String&gt; song = new HashMap&lt;String, String&gt;();
        song = data.get(position);

        // Setting all values in listview
        title.setText(song.get(CustomizedListView.KEY_TITLE));
        artist.setText(song.get(CustomizedListView.KEY_ARTIST));
        duration.setText(song.get(CustomizedListView.KEY_DURATION));
        imageLoader.DisplayImage(song.get(CustomizedListView.KEY_THUMB_URL), thumb_image);
        return vi;
    }
}

6. Now open your MainActivity class and type the following code. In the following code I am getting xml from url and parsing it. While parsing I am storing all the xml data into HashMap and finally I am passing HashMap to LazyAdapter class.

package com.example.androidhive;

import java.util.ArrayList;
import java.util.HashMap;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;

public class CustomizedListView extends Activity {
	// All static variables
	static final String URL = "https://api.androidhive.info/music/music.xml";
	// XML node keys
	static final String KEY_SONG = "song"; // parent node
	static final String KEY_ID = "id";
	static final String KEY_TITLE = "title";
	static final String KEY_ARTIST = "artist";
	static final String KEY_DURATION = "duration";
	static final String KEY_THUMB_URL = "thumb_url";

	ListView list;
    LazyAdapter adapter;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		ArrayList&lt;HashMap&lt;String, String&gt;&gt; songsList = new ArrayList&lt;HashMap&lt;String, String&gt;&gt;();

		XMLParser parser = new XMLParser();
		String xml = parser.getXmlFromUrl(URL); // getting XML from URL
		Document doc = parser.getDomElement(xml); // getting DOM element

		NodeList nl = doc.getElementsByTagName(KEY_SONG);
		// looping through all song nodes &lt;song&gt;
		for (int I = 0; I &lt; nl.getLength(); i++) {
			// creating new HashMap
			HashMap&lt;String, String&gt; map = new HashMap&lt;String, String&gt;();
			Element e = (Element) nl.item(i);
			// adding each child node to HashMap key =&gt; value
			map.put(KEY_ID, parser.getValue(e, KEY_ID));
			map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));
			map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST));
			map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION));
			map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL));

			// adding HashList to ArrayList
			songsList.add(map);
		}

		list=(ListView)findViewById(R.id.list);

		// Getting adapter by passing xml data ArrayList
        adapter=new LazyAdapter(this, songsList);
        list.setAdapter(adapter);

        // Click event for single list row
        list.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView&lt;?&gt; parent, View view,
					int position, long id) {

			}
		});
	}
}

Add Permissions in AndroidManifest.xml

Open your AndroidManifest.xml file add two permissons INTERNET and WRITE_EXTERNAL_STORAGE.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
	package="com.example.androidhive" android:versionCode="1"
	android:versionName="1.0">
	<uses-sdk android:minSdkVersion="8" />

	<application android:icon="@drawable/icon" android:label="@string/app_name">
		<activity android:name=".CustomizedListView" android:label="@string/app_name">
			<intent-filter>
				<action android:name="android.intent.action.MAIN" />
				<category android:name="android.intent.category.LAUNCHER" />
			</intent-filter>
		</activity>
	</application>

	<uses-permission android:name="android.permission.INTERNET" />
	<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>

Also you need 5 more classes in order to run this project. I am giving the code for each class at the end of the article. After adding all the classes if you run the project it will show output like below
ListView Default State

android customized listview

ListView on Select State

android customized listview hover

Other Classes you needed to run this project

You also need to include following class which deals functionalities like fetching images from WEB, storing them in cache and clearing cache etc., Make sure that you included following files in your project.

XMLParser.java

package com.example.androidhive;

import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.util.Log;

public class XMLParser {

	// constructor
	public XMLParser() {

	}

	/**
	 * Getting XML from URL making HTTP request
	 * @param url string
	 * */
	public String getXmlFromUrl(String url) {
		String xml = null;

		try {
			// defaultHttpClient
			DefaultHttpClient httpClient = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(url);

			HttpResponse httpResponse = httpClient.execute(httpPost);
			HttpEntity httpEntity = httpResponse.getEntity();
			xml = EntityUtils.toString(httpEntity);

		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		// return XML
		return xml;
	}

	/**
	 * Getting XML DOM element
	 * @param XML string
	 * */
	public Document getDomElement(String xml){
		Document doc = null;
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {

			DocumentBuilder db = dbf.newDocumentBuilder();

			InputSource is = new InputSource();
		        is.setCharacterStream(new StringReader(xml));
		        doc = db.parse(is); 

			} catch (ParserConfigurationException e) {
				Log.e("Error: ", e.getMessage());
				return null;
			} catch (SAXException e) {
				Log.e("Error: ", e.getMessage());
	            return null;
			} catch (IOException e) {
				Log.e("Error: ", e.getMessage());
				return null;
			}

	        return doc;
	}

	/** Getting node value
	  * @param elem element
	  */
	 public final String getElementValue( Node elem ) {
	     Node child;
	     if( elem != null){
	         if (elem.hasChildNodes()){
	             for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
	                 if( child.getNodeType() == Node.TEXT_NODE  ){
	                     return child.getNodeValue();
	                 }
	             }
	         }
	     }
	     return "";
	 }

	 /**
	  * Getting node value
	  * @param Element node
	  * @param key string
	  * */
	 public String getValue(Element item, String str) {
			NodeList n = item.getElementsByTagName(str);
			return this.getElementValue(n.item(0));
		}
}

ImageLoader.java

package com.example.androidhive;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;

public class ImageLoader {

    MemoryCache memoryCache=new MemoryCache();
    FileCache fileCache;
    private Map&lt;ImageView, String&gt; imageViews=Collections.synchronizedMap(new WeakHashMap&lt;ImageView, String&gt;());
    ExecutorService executorService; 

    public ImageLoader(Context context){
        fileCache=new FileCache(context);
        executorService=Executors.newFixedThreadPool(5);
    }

    final int stub_id = R.drawable.no_image;
    public void DisplayImage(String url, ImageView imageView)
    {
        imageViews.put(imageView, url);
        Bitmap bitmap=memoryCache.get(url);
        if(bitmap!=null)
            imageView.setImageBitmap(bitmap);
        else
        {
            queuePhoto(url, imageView);
            imageView.setImageResource(stub_id);
        }
    }

    private void queuePhoto(String url, ImageView imageView)
    {
        PhotoToLoad p=new PhotoToLoad(url, imageView);
        executorService.submit(new PhotosLoader(p));
    }

    private Bitmap getBitmap(String url)
    {
        File f=fileCache.getFile(url);

        //from SD cache
        Bitmap b = decodeFile(f);
        if(b!=null)
            return b;

        //from web
        try {
            Bitmap bitmap=null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is=conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
            Utils.CopyStream(is, os);
            os.close();
            bitmap = decodeFile(f);
            return bitmap;
        } catch (Exception ex){
           ex.printStackTrace();
           return null;
        }
    }

    //decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f){
        try {
            //decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);

            //Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE=70;
            int width_tmp=o.outWidth, height_tmp=o.outHeight;
            int scale=1;
            while(true){
                if(width_tmp/2&lt;REQUIRED_SIZE || height_tmp/2&lt;REQUIRED_SIZE)
                    break;
                width_tmp/=2;
                height_tmp/=2;
                scale*=2;
            }

            //decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize=scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {}
        return null;
    }

    //Task for the queue
    private class PhotoToLoad
    {
        public String url;
        public ImageView imageView;
        public PhotoToLoad(String u, ImageView i){
            url=u;
            imageView=i;
        }
    }

    class PhotosLoader implements Runnable {
        PhotoToLoad photoToLoad;
        PhotosLoader(PhotoToLoad photoToLoad){
            this.photoToLoad=photoToLoad;
        }

        @Override
        public void run() {
            if(imageViewReused(photoToLoad))
                return;
            Bitmap bmp=getBitmap(photoToLoad.url);
            memoryCache.put(photoToLoad.url, bmp);
            if(imageViewReused(photoToLoad))
                return;
            BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
            Activity a=(Activity)photoToLoad.imageView.getContext();
            a.runOnUiThread(bd);
        }
    }

    boolean imageViewReused(PhotoToLoad photoToLoad){
        String tag=imageViews.get(photoToLoad.imageView);
        if(tag==null || !tag.equals(photoToLoad.url))
            return true;
        return false;
    }

    //Used to display bitmap in the UI thread
    class BitmapDisplayer implements Runnable
    {
        Bitmap bitmap;
        PhotoToLoad photoToLoad;
        public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
        public void run()
        {
            if(imageViewReused(photoToLoad))
                return;
            if(bitmap!=null)
                photoToLoad.imageView.setImageBitmap(bitmap);
            else
                photoToLoad.imageView.setImageResource(stub_id);
        }
    }

    public void clearCache() {
        memoryCache.clear();
        fileCache.clear();
    }

}

MemoryCache.java

package com.example.androidhive;

import java.lang.ref.SoftReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import android.graphics.Bitmap;

public class MemoryCache {
    private Map&lt;String, SoftReference&lt;Bitmap&gt;&gt; cache=Collections.synchronizedMap(new HashMap&lt;String, SoftReference&lt;Bitmap&gt;&gt;());

    public Bitmap get(String id){
        if(!cache.containsKey(id))
            return null;
        SoftReference&lt;Bitmap&gt; ref=cache.get(id);
        return ref.get();
    }

    public void put(String id, Bitmap bitmap){
        cache.put(id, new SoftReference&lt;Bitmap&gt;(bitmap));
    }

    public void clear() {
        cache.clear();
    }
}

Utils.java

package com.example.androidhive;

import java.io.InputStream;
import java.io.OutputStream;

public class Utils {
    public static void CopyStream(InputStream is, OutputStream os)
    {
        final int buffer_size=1024;
        try
        {
            byte[] bytes=new byte[buffer_size];
            for(;;)
            {
              int count=is.read(bytes, 0, buffer_size);
              if(count==-1)
                  break;
              os.write(bytes, 0, count);
            }
        }
        catch(Exception ex){}
    }
}

FileCache.java

package com.example.androidhive;

import java.io.File;
import android.content.Context;

public class FileCache {

    private File cacheDir;

    public FileCache(Context context){
        //Find the dir to save cached images
        if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
            cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");
        else
            cacheDir=context.getCacheDir();
        if(!cacheDir.exists())
            cacheDir.mkdirs();
    }

    public File getFile(String url){
        //I identify images by hashcode. Not a perfect solution, good for the demo.
        String filename=String.valueOf(url.hashCode());
        //Another possible solution (thanks to grantland)
        //String filename = URLEncoder.encode(url);
        File f = new File(cacheDir, filename);
        return f;

    }

    public void clear(){
        File[] files=cacheDir.listFiles();
        if(files==null)
            return;
        for(File f:files)
            f.delete();
    }

}
This image for thumbnail purpose
android custom listview
Subscribe
Notify of
guest
669 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Mark
Mark
7 years ago

HI!
i want to display orginal image as downloaded from url, which line i need to change ?

Puneet
Puneet
7 years ago

getting error in xml parser

04-22 15:43:31.903: E/Error:(739): expected: /meta read: head (position:END_TAG @15:10 in java.io.StringReader@40e2a9d8)

Ivan Sanchez
Ivan Sanchez
7 years ago

Hi, thank you very much for your fantastic code. A have a question, how i can load an image from sdcard or internal device? I’m trying it but i don’t find the correct answer. Sorry for my english and for my question, i’m beginner at android. Thank you very much again, bye bye

nithu
nithu
7 years ago

Sir while implementing the given code unfortunately my UI stopped.Logcat showing error in HttpResponse in XMLParser and String XML in Main Activity.How can I rectify that sir.Please reply me.

Firdi
Firdi
7 years ago

Thanks Ravi! It’s amazing that you have shared this brilliant piece of code here. Just typing this in, getting it to run and trying to understand the concepts you used have taught me more in one day than I would understand in weeks. Thanks again for the good work.

Firdi
Firdi
7 years ago

It would have been a much more honest tutorial if Ravi would have provided a link to the MIT licensed LazyList library that he has used for his lazy image loading caching concepts.

Mutsuo Sims Kıymaz
7 years ago

Can’t download the file. Any problems maybe?

Valerio
Valerio
7 years ago

I downloaded this tutorial but this is logcat with error:
Please help me, i need this tutorial ^^

05-04 19:58:16.561: E/Trace(1311): error opening trace file: No such file or directory (2)

05-04 19:58:17.511: E/Error:(1311): expected: /hr read: body (position:END_TAG @6:8 in java.io.StringReader@4121e2b8)

05-04 19:58:17.511: D/AndroidRuntime(1311): Shutting down VM

05-04 19:58:17.521: W/dalvikvm(1311): threadid=1: thread exiting with uncaught exception (group=0x40a13300)

05-04 19:58:17.531: E/AndroidRuntime(1311): FATAL EXCEPTION: main

05-04 19:58:17.531: E/AndroidRuntime(1311): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.androidhive/com.example.androidhive.CustomizedListView}: java.lang.NullPointerException

05-04 19:58:17.531: E/AndroidRuntime(1311): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2059)

05-04 19:58:17.531: E/AndroidRuntime(1311): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)

05-04 19:58:17.531: E/AndroidRuntime(1311): at android.app.ActivityThread.access$600(ActivityThread.java:130)

05-04 19:58:17.531: E/AndroidRuntime(1311): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)

05-04 19:58:17.531: E/AndroidRuntime(1311): at android.os.Handler.dispatchMessage(Handler.java:99)

05-04 19:58:17.531: E/AndroidRuntime(1311): at android.os.Looper.loop(Looper.java:137)

05-04 19:58:17.531: E/AndroidRuntime(1311): at android.app.ActivityThread.main(ActivityThread.java:4745)

05-04 19:58:17.531: E/AndroidRuntime(1311): at java.lang.reflect.Method.invokeNative(Native Method)

05-04 19:58:17.531: E/AndroidRuntime(1311): at java.lang.reflect.Method.invoke(Method.java:511)

05-04 19:58:17.531: E/AndroidRuntime(1311): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)

05-04 19:58:17.531: E/AndroidRuntime(1311): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)

05-04 19:58:17.531: E/AndroidRuntime(1311): at dalvik.system.NativeStart.main(Native Method)

05-04 19:58:17.531: E/AndroidRuntime(1311): Caused by: java.lang.NullPointerException

05-04 19:58:17.531: E/AndroidRuntime(1311): at com.example.androidhive.CustomizedListView.onCreate(CustomizedListView.java:43)

05-04 19:58:17.531: E/AndroidRuntime(1311): at android.app.Activity.performCreate(Activity.java:5008)

05-04 19:58:17.531: E/AndroidRuntime(1311): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)

05-04 19:58:17.531: E/AndroidRuntime(1311): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)

05-04 19:58:17.531: E/AndroidRuntime(1311): … 11 more

Ravalesh
Ravalesh
7 years ago
Reply to  Valerio

I got the Same error. Used HttpGet httpPost=new HttpGet(url); instead of HttpPost httpPost = new HttpPost(url);inside getXmlFromUrl procedure. Worked fine.

huuhuybn
huuhuybn
7 years ago
Reply to  Ravalesh

because get data from url xml error.you shounld get data xml from other :).i try and run app ok 🙂

maryllien
maryllien
7 years ago
Reply to  Ravalesh

i’ve tried what you’ve said… but it’s still giving me nullpointerexception…..

ltd
ltd
7 years ago
Reply to  Ravalesh

YEAH, thanks

Huynh
Huynh
7 years ago
Reply to  Valerio

String xml = parser.getXmlFromUrl(URL); —> this error,return null :D,

you have to get data from other

maryllien
maryllien
7 years ago
Reply to  Huynh

from other what??? other xml????
i’m sorry… i’m new to this… i haven’t used xml parsing before…

huuhuybn
huuhuybn
7 years ago
Reply to  maryllien

create new xml and parsing xml yourself 🙂

Robbie
Robbie
7 years ago

Is it at all possible to add Async tasking to this so that it works in 4.0+?

Thanks

borg
borg
7 years ago

hello…i download this code and fix her properties but it does not work…it display (force close)…

caesardo
caesardo
7 years ago
Reply to  borg

change the HttpPost to HttpGet in getXmlFromUrl method in XmlParser class.. works like charm

Satish Kumar
Satish Kumar
7 years ago
Reply to  caesardo

still am getting same problem

Fahad Khan
Fahad Khan
7 years ago
Reply to  caesardo

Perfect!

Ibrahem Al-Betar
Ibrahem Al-Betar
7 years ago
Reply to  Fahad Khan

Yes the problem is solved 🙂

Karen
Karen
7 years ago
Reply to  borg

You have to download the xml file and put it in your own server, and then change the HttpPost to HttpGet.

Ragumanikandan
Ragumanikandan
7 years ago
Reply to  Karen

its working without downloading the xml.. Thanks..

Emrullah Lüleci
Emrullah Lüleci
7 years ago

this code has some problem at Activity a=(Activity)photoToLoad.imageView.getContext();in PhotosLoader class. Somehow it cannot take the activity of the imageView and doesn’t run the BitmapDisplayer on Ui thread. So I took the activity as parameter and called the runOnUiThread directly from activity and it worked. I couldn’t understand the reason but solution is this.

Mazen Kasser
Mazen Kasser
7 years ago

Can you please show in code what did you do? I am a beginner to Android and its been two days… the sample code never worked, I am using Mac, so I have no idea how all these people got it working!

Jason
Jason
7 years ago

Someone is selling this FREE excellent tutorial on chupamobile for $19. Here’s the link. http://www.chupamobile.com/products/details/795/Custom+ListView+with+Images+and+Text/

Mazen Kasser
Mazen Kasser
7 years ago
Reply to  Jason

I am ready to buy it if it works!

Mazen Kasser
Mazen Kasser
7 years ago

Well it looks great tutorial. I have downloaded the source code tried to launch the project and didn’t work, with showing “Unfortunately, CustomizedListView has stopped…” so people can you please, for God Sake, stop asking repeated questions and let us just to get the solution for this issue!!!

Mazen Kasser
Mazen Kasser
7 years ago

Can you please tell me why the sample code is not working!

Sid
Sid
7 years ago

It’s not running throwing null pointer exception

Sameer
Sameer
7 years ago

This Amazing tutorial about ListView with Image And Text. I love androidHive

Rahul
Rahul
7 years ago

hi

i am rahul i have downloaded whole code and when i executed this project then i getting an error in CustomizedListView class at line 43 (NodeList nl = doc.getElementsByTagName(KEY_SONG);) error message is Caused by: java.lang.NullPointerException

so provide solution why i am getting error…………

MarCo
MarCo
7 years ago
Reply to  Rahul

yeah… me too… the logcat always give me a null pointer exception… how can i make it run??? please help… i really need help….

sanjay
sanjay
7 years ago
Reply to  MarCo

This xml parsing Error please change the URL and (KEY_SONG);) Nod and chield nod change………..

alen
alen
7 years ago

Very useful codes,But when I tried with other “URL” and key values it doesn’t work ,it gets stuck in a loading page when i try to run the app.So can you please give me some suggestions regarding what all changes I need to do get the app executing properly with the new Url.

Thanks in Advance

rajesh
rajesh
7 years ago

nice tutorial………..

Vbk
Vbk
7 years ago

nice tutorial thanx

Krishna Veni
Krishna Veni
7 years ago

Hi Amit Suro & & Dsireesha0309 ., i have passing image from one activity to another activity using following code.its working well…

ImageLoader imageLoader = new ImageLoader(getApplicationContext());

final ImageView ima = (ImageView) findViewById(R.id.icon);
imageLoader.DisplayImage(_Image, ima);

Vikas B L
Vikas B L
7 years ago

I tried onclick listener. But it is not working. I don’t what the problem in it. Even my eclipse not generating R.java. Please suggest any solution.

priyanga Ranasinghe
priyanga Ranasinghe
7 years ago

This is Nice Tutorial.

So, How can add Search view to this list. I try to used Text Watcher but it not success. here my code I used in Main Activity.

adapter = new CustomListViewAdapter(this,R.layout.list_row, rowItems);
listView.setAdapter(adapter);
listView.setTextFilterEnabled(true);

editText.addTextChangedListener(new TextWatcher() {

public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {

}

public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {

}

public void afterTextChanged(Editable arg0) {
ActivityName.this.adapter.getFilter().filter(arg0);

}
});

Help me

Thank you.

mario
mario
7 years ago

pretty good tutorial !
Thanks for that …

Ahmed Sabry
Ahmed Sabry
7 years ago

Thanks Man!!

Writwick Daz
Writwick Daz
7 years ago

Why are you specifying “hdpi”? AFAIK, This is not resolution specific.

MarCo
MarCo
7 years ago

hi… im marco… i downloaded the code… but it didn’t work… then i try to simulate step by step of your tutorial, and i did also copy the codes posted here… but it still didn’t work… the logcat always give me a NullPointerException… what should i do to make it run??? please help….

muriel
muriel
7 years ago

hi ravi…. i have downloaded your code but when i run it,,, it gives me null pointer exception… why was that??? please need answer….

Mesud emre
Mesud emre
7 years ago

Can we use loading image jar to load the images?

MacBloke
MacBloke
7 years ago

Great tutorial.

One question, though. I want to use a list view to view an XML feed in a fragment and all I can get is a blank list view. My code is below – where am I going wrong?

package com.macbloke.fragmentlistview;

import android.net.Uri;

import android.os.AsyncTask;

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import org.apache.http.HttpResponse;

import org.apache.http.client.ClientProtocolException;

import org.apache.http.client.methods.HttpGet;

import org.apache.http.impl.client.DefaultHttpClient;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.NodeList;

import org.xmlpull.v1.XmlPullParser;

import org.xmlpull.v1.XmlPullParserException;

import org.xmlpull.v1.XmlPullParserFactory;

import java.io.IOException;

import java.io.InputStream;

import java.net.MalformedURLException;

import java.net.URI;

import java.net.URISyntaxException;

import java.net.URL;

import java.util.ArrayList;

import java.util.List;

import java.net.*;

import java.io.*;

import java.util.*;

import android.app.ListActivity;

import android.content.Context;

import android.content.Intent;

import android.os.Bundle;

import android.view.LayoutInflater;

import android.view.Menu;

import android.view.MenuInflater;

import android.view.MenuItem;

import android.view.View;

import android.view.ViewGroup;

import android.widget.ArrayAdapter;

import android.widget.ListAdapter;

import android.widget.ImageButton;

import android.widget.ListView;

import android.widget.SimpleAdapter;

import android.app.ListFragment;

public class Fragment3 extends Fragment {

// All static variables

static final String URL = “http://www.someurl.com/rss/news”;

// XML node keys

static final String KEY_ITEM = “item”; // parent node

static final String KEY_TITLE = “title”;

static final String KEY_DATE = “pubDate”;

static final String KEY_LINK = “link”;

static final String KEY_DESC = “description”;

ListView rssListView;

LazyAdapter rssAdapter;

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View root = inflater.inflate(R.layout.fragment3, container, false);

// Download the data

ArrayList<HashMap> rssArticleList = new ArrayList<HashMap>();

XMLParser parser = new XMLParser();

String xml = parser.getXmlFromUrl(URL); // getting XML from URL

Document doc = parser.getDomElement(xml); // getting DOM element

NodeList nl = doc.getElementsByTagName(KEY_TITLE);

// looping through all article nodes

for (int i = 0; i < nl.getLength(); i++) {

// creating new HashMap

HashMap map = new HashMap();

Element e = (Element) nl.item(i);

// adding each child node to HashMap key => value

map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE));

map.put(KEY_DATE, parser.getValue(e, KEY_DATE));

map.put(KEY_LINK, parser.getValue(e, KEY_LINK));

map.put(KEY_DESC, parser.getValue(e, KEY_DESC));

// adding HashList to ArrayList

rssArticleList.add(map);

}

rssListView=(ListView)root.findViewById(R.id.list);

// Getting adapter by passing xml data ArrayList

rssAdapter=new LazyAdapter(getActivity(), rssArticleList);

rssListView.setAdapter(rssAdapter);

return root;

}

}

MacBloke
MacBloke
7 years ago
Reply to  MacBloke

D’Oh!

Replaced:

NodeList nl = doc.getElementsByTagName(KEY_TITLE);

with:

NodeList nl = doc.getElementsByTagName(KEY_ITEM);

All is now well.

ujjwal
ujjwal
7 years ago

indeed a good tutorial…as i am a beginner in android..and i am running the tutorial its not working..so wud u please tell me how can i get it working…ASAP..

Osama Mursleen
Osama Mursleen
7 years ago

Good Tutorial….

Edward Lee
Edward Lee
7 years ago

Hi Adroid, use notifyDataSetInvalidated() may resolve you problem.

Darpan
Darpan
7 years ago

This is one great post. Very elaborated tutorial. Good work !

Edward Lee
Edward Lee
7 years ago

Dear, friend. I have pass this tutorial code to my GitHub ( https://github.com/EdwardLee03/android_tutorial/tree/master/ListView ), that is run OK. Good luck!

IDE: Android Studio
Android Version: 4.0.3

The following is difference point:
MusicActivity.java

protected void onCreate(Bundle savedInstanceState) {
if (DEVELOPER_MODE) {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.build());
}

super.onCreate(savedInstanceState);

AdapterView.OnItemClickListener itemClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view, int position, long id) {
Map song = (Map) adapter.getItem(position);
ImageView thumbImage = (ImageView) view.findViewById(R.id.thumb_image);
ImageLoader imageLoader = adapter.getImageLoader();
imageLoader.displayImage(song.get(Song.THUMB_URL), thumbImage);
adapter.notifyDataSetInvalidated();
}
}
};

LazyAdapter.java

public View getView(int position, View view, ViewGroup viewGroup) {

this.notifyDataSetChanged(); // Important!

return view;
}

ImageLoader.java

private Bitmap getBitmap(String imageUrl) {

// from Web
try {
URL url = new URL(imageUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(3000);
conn.setReadTimeout(10000);
conn.setInstanceFollowRedirects(true);
conn.setRequestMethod(“GET”);
conn.setDoInput(true);
conn.connect();

InputStream in = conn.getInputStream();
OutputStream out = new FileOutputStream(file);
IOUtils.copy(in, out);
in.close();
out.close();
conn.disconnect();

bitmap = decodeFile(file);

}

MrH
MrH
7 years ago

Hi mate,

Thank you for this post. I am getting this error:

org.apache.harmony.xml.dom.ElementImpl cannot be cast to android.renderscript.Element

Any suggestion?

MrH
MrH
7 years ago
Reply to  MrH

Dont worry. I fixed it. It was me mistake. Your code it perfect.

Chathura Wijesinghe
7 years ago

I found you articles form here as well http://www.9android.net/custom-listview-image-text/. its horrible copying some ones articles and publish.

Giasafox
Giasafox
7 years ago

And what about if I want NOT to read the uploaded xml file, but to have a static xml file in the resources of my app and read the information from that??????
How can I implement this?????

howien
howien
7 years ago

Hi ravi,
i realized that, it cant functioned without internet connection. may i know how to make it functioned without internet connection? means that the images and the data will store in device maybe cache when first time access to the internet?

Thanks!

love
love
7 years ago

I was able to run this project. But when im trying to use my own xml file and my own url it seems like there’s a problem because it kept on stopping when i try to run it 🙁

mahmoud elsafy
mahmoud elsafy
7 years ago

exceptions in the logcat here :
1- HttpResponse httpResponse = httpClient.execute(httpPost);
2- String xml = parser.getXmlFromUrl(URL);

when i try to run the application unfortunately has stopped , please help me as i am new in android

Thorsten
Thorsten
7 years ago

Some remarks and best practices:

Don’t use right-pointing carets on line items: http://developer.android.com/design/patterns/pure-android.html

Don’t use SoftReference starting from Android 2.3 (better: use the LruCache from the Support Library): http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

Don’t use DOM (better: use the XmlPullParser as recommended by Google): http://developer.android.com/training/basics/network-ops/xml.html

Even better than XML: use JSON to reduce bandwidth consumtion/battery drainage and Google’s Volley networking library (as presented at the Google IO 2013): http://www.youtube.com/watch?v=yhv8l9F44qo and https://android.googlesource.com/platform/frameworks/volley/+/master

Don’t use Apache’s DefaultHttpClient starting from Android 2.3: http://android-developers.blogspot.de/2011/09/androids-http-clients.html

And finally: free resources and/or close streams always in a try-finally-construct.

Henrique Dn Maina
Henrique Dn Maina
7 years ago

Nice post. I like it and am using it.

However i have a question.

Instead of having an xml file, i want to use JSON data generated by a php with data as sampled below

success: 1,size: 3,
details: [
{
id : 1,
title : “Someone Like You”,
artise : “Adele”,
duration : “4:47”
thumb_url : “http://api.androidhive.info/music/images/adele.png”
},
{
id : 2,
title : “Someone Like You 2”,
artise : “Adele”,
duration : “4:47”
thumb_url : “http://api.androidhive.info/music/images/adele.png”
},
{
id : 3,
title : “Someone Like You 3”,
artise : “Adele”,
duration : “4:47”
thumb_url : “http://api.androidhive.info/music/images/adele.png”
}

]

Thorsten
Thorsten
7 years ago

And what is the question? How to generate JSON on server side? How to parse JSON on Android? Btw. the JSON example above isn’t valid: success and size are part of an JSONObject, so the whole fragment should be enclosed in curly braces.

Trollzito
Trollzito
7 years ago
Zeus
Zeus
7 years ago

Can u pls tell me how i can implement the above project using tab navigation and onclick to display the individual item the tab should still be visible, i tried to do it but onclick creates a new activity and the tab goes missing.
thnx

Abhishek Mirajkar
Abhishek Mirajkar
7 years ago

(Unfortunately, app has stopped)…
I changed HttpPost to HttpGet in XMLParser class but it showing me above error in AVD.
plz help….

Groxor
Groxor
7 years ago

Thanks! 😀 this source worked!

James Green
James Green
7 years ago

Thank you Ravi for the detailed description on Android Listview , there’s one more video I found on youtube link: https://www.youtube.com/watch?v=0zQCv0Xb3pk
other users should find this useful, it helped me alot

ihsanul
ihsanul
7 years ago

hi ravi
if i get image manual from folder drawable-hdpi
i dont use URL = “http://api.androidhive.info/music/music.xml”
how i can do it?
help me

Nirmal
Nirmal
7 years ago

so u can use image button instead of image

kozm
kozm
7 years ago
Reply to  Nirmal

Nirmal, I have used the imagebutton and facing issues with listitem random selection please take look on stackoverflow (http://stackoverflow.com/questions/18182601/listview-item-with-button-random-selection-while-scrolling) I posted for some help.

Martin
Martin
7 years ago

Hello. I would like to know if it is possible to have 400 elements in the xml file but only load 20 at a time in my application. Everytime my user reaches the bottom of the screen by scrolling, then the next 20 elements will be loaded and displayed. If this is possible, could You please supply the code needed. Thanks

669
0
Would love your thoughts, please comment.x
()
x