Like the article? You may like us on Facebook or follow us on Twitter.

Android ListView Tutorial

This post will walk you through Android ListView Tutorial for building simple and customized ListView using different Android adapters.

List is one of the most common UI patterns, which is being used extensively to display the collection of data elements in rows. In android ListView is a view group that displays a list of scrollable items. The list items are automatically inserted to the list using an Adapter that pulls content from a source such as an array.

1. Understanding Adapter

Adapter is basically bridge between UI components and the data source that fill data into UI Component. Adapter is used to supply the data to like spinner, list view, grid view etc. For example, we can create a list view from xml layout without data, and using adapter we can supply data sets to list view.

Android list view

If you look at the above images you will certainly get an idea of list view. This kind of customizable list views can be done using an adapter.

2. Building ListView using ArrayAdapter

This is the simplest way we can create a simple default styled list view from array of elements. To do this there are three things to concentrate,

  1. Find out what data you want to display in list: For our example, I am considered taking a static array of strings. But for complex scenarios it can be a response from server, or data fetched from database.
  2. Declare the list view object in your xml layout: ListView is the user interface element we are using to represent data to user. So in my example, the layout contains a list view. Make sure you provide an appropriate id.
  3. Now finally, feed the list view with the data sets: For this we use adapters. We can always customize our adapter, but for to start let’s make it simple. I am using Array adapter class available in android.

Here is how my layout file looks like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ListActivity" >
 
<ListView
android:id="@+id/months_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
 
</LinearLayout>
ListActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.javatechig.droid.ui;
 
import android.os.Bundle;
import android.app.Activity;
import android.widget.ArrayAdapter;
import android.widget.ListView;
 
public class ListActivity extends Activity {
 
	// Initialize the array
	String[] monthsArray = { "JAN", "FEB", "MAR", "APR", "MAY", "JUNE", "JULY",
 "AUG", "SEPT", "OCT", "NOV", "DEC" };
 
	// Declare the UI components
	private ListView monthsListView;
 
	private ArrayAdapter arrayAdapter;
 
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_list);
 
		// Initialize the UI components
		monthsListView = (ListView) findViewById(R.id.months_list);
		// For this moment, you have ListView where you can display a list.
		// But how can we put this data set to the list?
		// This is where you need an Adapter
 
		// context - The current context.
		// resource - The resource ID for a layout file containing a layout 
                // to use when instantiating views.
		// From the third parameter, you plugged the data set to adapter
		arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, monthsArray);
 
		// By using setAdapter method, you plugged the ListView with adapter
		monthsListView.setAdapter(arrayAdapter);
	}
}
Output of the above code is

3. Building ListView using Custom Adapter

If you have followed my previous example, then you are ready with a simple list which using ArrayAdapter. Now it’s the time to create something fancy. In this section of tutorial, you will find steps to customize a list using custom adapters.

In this above example I am displaying a new list items. Below is my NewsItem object

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class NewsItem {
 
	private String headline;
	private String reporterName;
	private String date;
 
	public String getHeadline() {
		return headline;
	}
 
	public void setHeadline(String headline) {
		this.headline = headline;
	}
 
	public String getReporterName() {
		return reporterName;
	}
 
	public void setReporterName(String reporterName) {
		this.reporterName = reporterName;
	}
 
	public String getDate() {
		return date;
	}
 
	public void setDate(String date) {
		this.date = date;
	}
 
	@Override
	public String toString() {
		return "[ headline=" + headline + ", reporter Name=" + 
				reporterName + " , date=" + date + "]";
	}
}

3.1. Create your custom row layout

I have creted a simple layout as shown in the image below, which holds news headline, reported name and date.
list_row_layout.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?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:minHeight="50dp"
    android:orientation="horizontal"
    android:padding="5dip" >
 
    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        android:textStyle="bold"
        android:typeface="sans" />
 
    <TextView
        android:id="@+id/reporter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/title"
        android:layout_marginTop="5dip"
        android:text=""
        android:textColor="#343434"
        android:textSize="12sp" />
 
    <TextView
        android:id="@+id/date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/reporter"
        android:layout_alignBottom="@+id/reporter"
        android:layout_alignParentRight="true"
        android:text=""
        android:textColor="#343434"
        android:textSize="12sp" />
 
</RelativeLayout>

3.2. Writing a custom adapter

CustomListAdapter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class CustomListAdapter extends BaseAdapter {
 
	private ArrayList listData;
 
	private LayoutInflater layoutInflater;
 
	public CustomListAdapter(Context context, ArrayList listData) {
		this.listData = listData;
		layoutInflater = LayoutInflater.from(context);
	}
 
	@Override
	public int getCount() {
		return listData.size();
	}
 
	@Override
	public Object getItem(int position) {
		return listData.get(position);
	}
 
	@Override
	public long getItemId(int position) {
		return position;
	}
 
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder;
		if (convertView == null) {
			convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
			holder = new ViewHolder();
			holder.headlineView = (TextView) convertView.findViewById(R.id.title);
			holder.reporterNameView = (TextView) convertView.findViewById(R.id.reporter);
			holder.reportedDateView = (TextView) convertView.findViewById(R.id.date);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}
 
		holder.headlineView.setText(listData.get(position).getHeadline());
		holder.reporterNameView.setText("By, " + listData.get(position).getReporterName());
		holder.reportedDateView.setText(listData.get(position).getDate());
 
		return convertView;
	}
 
	static class ViewHolder {
		TextView headlineView;
		TextView reporterNameView;
		TextView reportedDateView;
	}
 
}

3.3. Putting it all together

Now we are ready with adapter and layout. Lets put all of them together and build a custom list.

activity_main.xml : This is my main activity layout. For making this example simpler, I just have a ListView inside a LinearLayout.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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/custom_list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:dividerHeight="1dp" />
 
</LinearLayout>

Here my activity class MainActivity.java where I am initializing list view and adapter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public class MainActivity extends Activity {
 
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
 
		ArrayList image_details = getListData();
		final ListView lv1 = (ListView) findViewById(R.id.custom_list);
		lv1.setAdapter(new CustomListAdapter(this, image_details));
		lv1.setOnItemClickListener(new OnItemClickListener() {
 
			@Override
			public void onItemClick(AdapterView<?> a, View v, int position, long id) {
				Object o = lv1.getItemAtPosition(position);
				NewsItem newsData = (NewsItem) o;
				Toast.makeText(MainActivity.this, "Selected :" + " " + newsData, Toast.LENGTH_LONG).show();
			}
 
		});
 
	}
 
	private ArrayList getListData() {
		ArrayList results = new ArrayList();
		NewsItem newsData = new NewsItem();
		newsData.setHeadline("Dance of Democracy");
		newsData.setReporterName("Pankaj Gupta");
		newsData.setDate("May 26, 2013, 13:35");
		results.add(newsData);
 
		newsData = new NewsItem();
		newsData.setHeadline("Major Naxal attacks in the past");
		newsData.setReporterName("Pankaj Gupta");
		newsData.setDate("May 26, 2013, 13:35");
		results.add(newsData);
 
		newsData = new NewsItem();
		newsData.setHeadline("BCCI suspends Gurunath pending inquiry ");
		newsData.setReporterName("Rajiv Chandan");
		newsData.setDate("May 26, 2013, 13:35");
		results.add(newsData);
 
		newsData = new NewsItem();
		newsData.setHeadline("Life convict can`t claim freedom after 14 yrs: SC");
		newsData.setReporterName("Pankaj Gupta");
		newsData.setDate("May 26, 2013, 13:35");
		results.add(newsData);
 
		newsData = new NewsItem();
		newsData.setHeadline("Indian Army refuses to share info on soldiers mutilated at LoC");
		newsData.setReporterName("Pankaj Gupta");
		newsData.setDate("May 26, 2013, 13:35");
		results.add(newsData);
 
		newsData = new NewsItem();
		newsData.setHeadline("French soldier stabbed; link to Woolwich attack being probed");
		newsData.setReporterName("Sudeep Nanda");
		newsData.setDate("May 26, 2013, 13:35");
		results.add(newsData);
 
		return results;
	}
}

3.4. Output

customised list view

4. Customizing ListView

ListView is one of the most used and a common control in android. To make the GUI attractive, we always customize and apply some theming. In this section of tutorial we will learn to customize an Android ListView with colors, gradients, etc. 

4.1. Change ListView selection colour in Android

We can change the ListView default selection color using Android selectors. Selectors enable us to decide what to show and how to show based on different states of each component. To make the example simplified, we will be changing the background color and text color while list row is pressed state.

Step-1

First create a list selector style in ‘drawable’ folder. I have named it as “list_selector_flatcolor.xml”. This style will be used to change the background color of list row when pressed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<selector xmlns:android="http://schemas.android.com/apk/res/android">
     <!-- Normal state. -->
    <item android:drawable="@color/list_row_default_bg" 
        android:state_pressed="false" 
        android:state_selected="false"/>
    <!-- pressed state. -->
    <item android:drawable="@color/list_row_pressed_bg" 
        android:state_pressed="true"/>
    <!-- Selected state. -->
    <item android:drawable="@color/list_row_selected_bg" 
        android:state_pressed="false" 
        android:state_selected="true"/>
 
</selector>
 Step-2

Now, create another selector style in ‘drawable’ folder. I have named it as “list_item_text_selector.xml”. This style will be used to change the text color while list row is pressed.

1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="@color/text_color_inverse" />
    <item android:state_focused="true" android:color="@color/text_color_inverse" />
    <item android:color="@color/text_color_default" />
</selector>
Step-3

Below are the colors, I have used in my example

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="text_color_default">#00000C</color>
    <color name="text_color_inverse">#FFFFFF</color>
    <color name="white">#FFFFFF</color>
    <color name="list_row_default_bg">#ffffff</color>
    <color name="list_row_pressed_bg">#008cef</color>
    <color name="list_row_selected_bg">#86d3f6</color>
</resources>
Step-4:

Now, change the following  in your “activity_main.xml” where ListView widget is declared.

1
2
3
4
5
6
 <ListView
        android:id="@+id/custom_list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:listSelector="@drawable/list_selector_flatcolor"
        android:dividerHeight="1dp" />

Now, we can apply the styles to text in “list_row_layout.xml”. Change all TextView widget textColor attribute as shown below

1
2
3
4
5
6
7
8
<TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        android:textColor="@drawable/list_item_text_selector"
        android:textStyle="bold"
        android:typeface="sans" />
Output:

android_list_example_with_list_selector

5. How to change the divider color in the ListView?

5.1. Changing ListView divider color and height

1
2
3
4
5
6
7
<ListView
        android:id="@+id/custom_list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:divider="#FF0000"
        android:dividerHeight="1dp"
        android:listSelector="@drawable/list_selector_flatcolor" />

5.2. Using a drawable for ListView divider

1
2
3
4
5
6
7
<ListView
        android:id="@+id/custom_list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:divider="@drawable/list_row_divider"
        android:dividerHeight="1dp"
        android:listSelector="@drawable/list_selector_flatcolor" />

5.3. Changing ListView divider color pragmatically

1
2
3
4
5
ListView listView = getListView();
ColorDrawable devidrColor = new ColorDrawable(
      this.getResources().getColor(R.color.devidrColor));
listView.setDivider(devidrColor);
listView.setDividerHeight(1);

listview row divider example

6. References

http://developer.android.com/guide/topics/ui/layout/listview.html http://developer.android.com/reference/android/widget/ListView.html

About Nilanchala

A blogger, bit of a tech freak and a software developer. Follow him on Twitter, or like our official Facebook page or Google Plus.

  • http://javatechig.com/ javatechig

    all java code should be in src folder, xml layouts in layout folder and resources files in drawable.

  • Didi

    Hi, I followed your example for selecting in a listview and it works perfectly, but what if I want to select more than 1 item, I tried adding android:choiceMode=”multipleChoice” in my listView, but it does not work

  • Eduardo Grotteschi

    I think you are trying to create a Tab layout. Check this tutorial: http://www.androidhive.info/2013/10/android-tab-layout-with-swipeable-views-1/

  • Kaneki Shiba

    Good tutorial, I just had to add clickable=”true” on my row container in order to react to the touch events otherwise nothing was going to change.

  • http://javatechig.com/ javatechig

    You may look at the below post, this will very much explains the same as your need.

    http://javatechig.com/android/json-feed-reader-in-android/

  • Nilanchala Panigrahy

    It is easy if you are using ViewHolder design pattern as explained in the above example. You can use below syntax

    holder.headlineView.setOnClickListener(onClickHandler);

  • Amo las maduras!

    ey men where are your from?

    • Nilanchala Panigrahy

      Bangalore, India

  • delsonica

    Great! Thank you

  • pkpdeveloper

    Superb Examples.

  • Rahul

    Fabulous Example Thanks very very much

  • Amo las maduras!

    hi men!

    As I can assign a space between items in a listview

  • http://www.thepcwizard.in/ Rohan Makkar

    great tutorial, easy to follow, thanks.

  • Coco

    great tutorial! thank u!!! :D

  • http://marki-tos.tumblr.com/ Todo poderoso

    excelent! just what i wanted!

    • Kame

      I thought all you wanted was dragonballz

  • http://www.techstarvation.wordpress.com/ Sumit Gupta

    This is the first time i am seeing a listview tutorial using ViewHolder pattern, while researching on it i found ViewHolder does improves performance. Thanks for the great tutorial

    http://developer.android.com/training/improving-layouts/smooth-scrolling.html

  • http://javatechig.com/ javatechig

    Oh yes. You can set TextView attribute in two ways.
    1. Using xml layout preview builder

    In this above code text, textColor, textStyle, typeface, etc are attributes for TextView.

    2. Programmatically from activity java code

    TextView title = (TextView) context.findViewById(R.id.title);
    title.setText();
    title. setHighlightColor()
    title.setHint()

    Above are setting TextView attributes using public method exposed.

    You may check out all list of methods and attributes available from below link

    http://developer.android.com/reference/android/widget/TextView.html

    • Arion argo

      hello again!

      i’m sorry i was so vague.
      i know that, but what i was asking was, if it possible to to that through the dynamic part of your example?

      thanks again

      • http://javatechig.com/ javatechig

        Sure, it is quite possible. For that you just need to call the methods like

        holder.headlineView.setText("Your text goes here");

        You can set attributes by calling all available methods of TextView.

  • Matt Fuller

    Hi there!

    Thanks for this, this is awesome, I’ve been looking for a better way of creating a list view and this did the trick by pointing me in the right direction. How would you add a different image to each list item using your method? I’d appreciate any pointers you might have.

    Cheers,

    • http://javatechig.com/ javatechig

      Hi Matt,
      Check out my another tutorial on “Asynchronous Image Loader in Android ListView”

      http://javatechig.com/android/asynchronous-listview-android/

      I am sure this is what you are looking at.

      • Matt Fuller

        Thank you! Pointed me in the right direction to get it sorted. :) Any chance I could request a tutorial? I’d like to load local HTML files from the device depending on the list item checked and I’m having a hard time. I’d appreciate any help. Thanks again.

        • http://javatechig.com/ javatechig

          You need to use onItemClickListener for handling the list item click events as in my example
          lv1.setOnItemClickListener(new OnItemClickListener() {

          @Override
          public void onItemClick(AdapterView a, View v, int position, long id) {
          Object o = lv1.getItemAtPosition(position);
          NewsItem newsData = (NewsItem) o;
          Toast.makeText(MainActivity.this, "Selected :" + " " + newsData, Toast.LENGTH_LONG).show();
          }

          });

          Now, moving on to load html pages
          If you want to load html pages, you can use WebView in android, which can either load a html from a remote server or from a web url. Find a working example below.

          http://javatechig.com/android/android-webview-example/

          If you are looking for displaying some html text on a TextView you can still do that. My below post will help you.

          http://javatechig.com/android/display-html-in-android-textview/

  • http://twitter.com/ChrisMayhew87 Christopher Mayhew

    @JavaTechIG Cheers! Your site is good :)

  • http://twitter.com/ChrisMayhew87 Christopher Mayhew

    @JavaTechIG I used your tutorial to help me code a custom listview but I’m having trouble with the array bit and accessing the getDate() etc

  • Christopher Mayhew

    I’ve adjusted this to work with my code but the following bit is throwing errors.
    holder.headlineView.setText(listData.get(position).getHeadline());
    holder.reporterNameView.setText(“By, ” + listData.get(position).getReporterName());
    holder.reportedDateView.setText(listData.get(position).getDate());

    I get this error on them lines
    The method getHeadline() is undefined for the type Object

    Any help?!

    • http://javatechig.com/ javatechig

      Hi Christopher,
      Instead of directly accessing methods, you may typecast it to its type. Use the below code

      NewsItem newsItem = (NewsItem)listData.get(position);
      holder.headlineView.setText(newsItem.getHeadline());
      holder.reporterNameView.setText(“By, ” + newsItem.getReporterName());
      holder.reportedDateView.setText(newsItem.getDate());

      • Christopher Mayhew

        Excellent!! Thank you!