Building a Custom Fancy ListView in Android

In this tutorial we will walk through the process of building a custom ListView with alternate background colors and an image icon set to every row.

The final result will look like in the screenshot below:

Android fancy listview

 

1. We will begin by creating a new project in Eclipse.
Project name = FancyList
Activity name = FancyListActivity

2. Put the icon you want to display in the list, in one of the drawable folders, for example I put the arrow icon in the drawable-mdpi folder. Make sure the name of the icon is called arrow_icon.png.

3. Open the main.xml layout file and add a ListView view with the list id:

<ListView
     android:id="@+id/list"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content" />

 

4. Create a new layout file named row.xml. This layout file will reprezent each row in the list and should contain a TextView and an ImageView.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content" >
  
             <TextView
                 android:id="@+id/headline"
                 android:layout_width="0px"
                 android:layout_height="wrap_content"
                 android:layout_weight="0.8"
                 android:padding="10dp"
                 android:textSize="16dp"
                 android:textColor="#FFF"/>
 
             <ImageView
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="center_vertical|right"
                 android:layout_marginRight="6dp"
                 android:src="@drawable/arrow_icon" />
 
 </LinearLayout>

 

5. Open the main activity, in our case FancyListActivity.java, and add a String array instance variable that will contain the text to be displayed in the list:

public class FancyListActivity extends Activity {
   String[] items = { &quot;Test text 1&quot;, &quot;Test text 2&quot;, &quot;Test text 3&quot;, &quot;Test text 4&quot;, &quot;Test text 5&quot;, &quot;Test text 6&quot; };

 

6. Modify the onCreate() method to look like this:

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

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

   SpecialAdapter adapter = new SpecialAdapter(this, items);
   list.setAdapter(adapter);
}

At this stage you may notice that Eclipse shows you an error saying that the class SpecialAdapter is not defined.
It’s OK for now, because we will define it a bit later.

 

7. Just after the onCreate() method, add the following static class.

static class ViewHolder {
    TextView text;
}

This class will hold a reference to our TextView control defined earlier in the row.xml layout file.

 

8. In order to customize the list to look like we want, with alternate colors, we should define our own list adapter. Basically, this is achieved by extending the BaseAdapter class and providing our own implementation of methods.


private class SpecialAdapter extends BaseAdapter {
//Defining the background color of rows. The row will alternate between green light and green dark.
private int[] colors = new int[] { 0xAAf6ffc8, 0xAA538d00 };
private LayoutInflater mInflater;

//The variable that will hold our text data to be tied to list.
private String[] data;

public SpecialAdapter(Context context, String[] items) {
    mInflater = LayoutInflater.from(context);
    this.data = items;
}

@Override
public int getCount() {
    return data.length;
}

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

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

//A view to hold each row in the list
@Override
public View getView(int position, View convertView, ViewGroup parent) {

// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
ViewHolder holder;

if (convertView == null) {
    convertView = mInflater.inflate(R.layout.row, null);

    holder = new ViewHolder();
    holder.text = (TextView) convertView.findViewById(R.id.headline);
    convertView.setTag(holder);
} else {
    holder = (ViewHolder) convertView.getTag();
}
    // Bind the data efficiently with the holder.
    holder.text.setText(data[position]);

    //Set the background color depending of  odd/even colorPos result
    int colorPos = position % colors.length;
    convertView.setBackgroundColor(colors[colorPos]);

   return convertView;
}
}

This is it! By this time you should successfully compile and run the application. If there’re any issues feel free to write them in comments.

Please visit the Android Tutorials page for more tutorials.

33 thoughts on “Building a Custom Fancy ListView in Android

  1. Hi this is a very good example.. but i am getting null pointer exception because the ListView list=(ListView) findViewById(R.id.list) is null… dont know how… I have a list also

    1. Hi,

      There are many situations when an app could throw NullPointerException. The most obvious reason is that the object where the reference is pointing to, is null or not instantiated.

      Once again carefully check your XML layout file and code.

      If you could upload your source code (XML layout files and Java code) somewhere, I could check it and see what’s going on.

      You can upload your source code to http://pastebin.com and share the link.

    1. Hi,
      I tested your code and everything looks fine on my side, the program runs without NullPointerException.

      What can I recommend you is to try to clean your project, in Eclipse: go to Project -> Clean -> Select current project -> OK. And then run the project again.

    1. 1. You will need to set a listener to your ListView and override the onItemClick method.
      2. To launch an activity you start an intent, like this:
      Intent i=new Intent(FancyListActivity.this, ActivityYouWantToStart.class);
      startActivity(i);

      Somewhere in the onCreate() method add this code:
      list.setOnItemClickListener(new OnItemClickListener() {
      public void onItemClick(AdapterView parent, View view,
      int position, long id) {

      // When clicked, open the "NewActivity" activity
      Intent i=new Intent(FancyListActivity.this, NewActivity.class);
      startActivity(i);
      }
      });

      The above code assumes there’s a “NewActivity” activity available.
      (Don’t forget to add it to AndroidManifest file)

      To consolidate your knowledge, I really suggest you take a look over the Android’s ListView tutorial: http://developer.android.com/resources/tutorials/views/hello-listview.html

  2. my doubt is

    list.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView parent, View view,
    int position, long id) {

    String item =(String) list.getAdapter().getItem(position);

    // When clicked, show a toast with the value

    Toast.makeText(getApplicationContext(),”clicked:” +item,
    Toast.LENGTH_SHORT).show();
    }
    });

    I want “item” to come on toast… but its throwing exception as

    03-13 18:39:15.410: ERROR/AndroidRuntime(6811): java.lang.ClassCastException: java.lang.Integer

    so how to get the String item when i click on list???

  3. no this is not working

    03-14 10:40:57.910: ERROR/AndroidRuntime(7518): FATAL EXCEPTION: main
    03-14 10:40:57.910: ERROR/AndroidRuntime(7518): java.lang.ClassCastException: android.widget.LinearLayout

    this is the exception

  4. Thank you… but it dint work for me 😦 i have one more issue..
    how to start a thread of long process.. then start spinner.. in main thread….
    stop the spinner only when background process is finished
    then go to next statement

  5. hello..i have one problem, in my RSS is tag with link to another RSS, how can i use this link in listview to connect to another listview..

  6. Hey, That’s Awesome Tutorail!!.. but as am a beginner now, so not getting how the following statements are wrking here.. can u pls breiefly describe!!…
    Thank u… 🙂

    int colorPos = position % colors.length;
    convertView.setBackgroundColor(colors[colorPos]);

    1. Here we set the background color of currently row in the ListView.
      The 2 colors are stored in an array: colors[] = { 0xAAf6ffc8, 0xAA538d00 }; , these are the hexadecimal values for green light, and green dark. So we want when the getView() is called for every row, one time to pick the first color from the array, another time to pick the second color from the array, and so on alternate between these 2 colors.

      To alternate between background colors, here we do a simple trick.
      We do a module operation (%) between the “position” of an element in adapter, and the length of colors[] array – which always is 2 (as we store in it only 2 colors) – and store the result in the “colorPos” variable:

      int colorPos = position % colors.length;
      

      Every time when the “position” is an even number, we get “0” as the result, and every time when the “position” is an odd number we get “1” as the result.

      So, depending of the “colorPos” value, one time it will point to first element in the array (green light), and the other time it will point to second element in the array (green dark):

      convertView.setBackgroundColor(colors[colorPos]);
      

      And in this way we achieve the alternate background effect.

  7. hii i got a quetion step 8 saids : In order to customize the list to look like we want, with alternate colors, we should define our own list adapter. Basically, this is achieved by extending the BaseAdapter class and providing our own implementation of methods.

    where can i find the baseadapter to extend it?/

  8. Hi
    I just loved ur tutorial ….i want your help ….. if we donot want to connect headlines with android browser but want to show that headlines in different screen what is code for that

  9. You are right, the TableLayout is unnecessary and I removed it.
    This is one of my first posts, when I was just starting with Android and was more prone to writing redundant code 🙂

    Thanks for pointing it out and for the reference.

Leave a reply to house un-american activities committee Cancel reply