Home > Tutorials, User Interface > Building a Custom Fancy ListView in Android

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" >
</ListView>

 

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.

I used a table layout with 2 columns to arrange the TextView and ImageView both in the same line.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content" >

     <TableLayout
         android:id="@+id/tableLayout1"
         android:layout_width="match_parent"
         android:layout_height="wrap_content" >

         <TableRow >

             <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" />
         </TableRow>
     </TableLayout>
 </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 = { "Test text 1", "Test text 2", "Test text 3", "Test text 4", "Test text 5", "Test text 6" };

 

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.

About these ads
  1. Vidya
    March 12, 2012 at 12:38 pm

    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

    • March 12, 2012 at 8:37 pm

      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.

  2. Vidya
    March 13, 2012 at 5:25 am

    Hi..http://pastebin.com/fUDiy1h3 here is my code… please let me know why list is a null

    • March 13, 2012 at 6:20 am

      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.

  3. Vidya
    March 13, 2012 at 11:30 am

    yes.. it worked fine now after cleaning :) thank you so much

  4. Vidya
    March 13, 2012 at 11:53 am

    I have one more issue… How to make this list Clickable?? and redirect to other activity on Click??

    • March 13, 2012 at 9:33 pm

      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

  5. Vidya
    March 14, 2012 at 5:14 am

    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???

    • March 14, 2012 at 6:10 am

      Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
      Toast.LENGTH_SHORT).show();

  6. Vidya
    March 14, 2012 at 6:31 am

    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

    • March 14, 2012 at 8:39 am

      Try this:
      String text=(String)(list.getItemAtPosition(position));

  7. Vidya
    March 16, 2012 at 12:55 pm

    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

  8. April 1, 2012 at 5:47 pm

    This is one of the best tutorials I have seen online. I have a book that I use while learning Android Dev but I had to pause the learning alittle bit due to time constraints. I will soon start over! Thanks.
    http://www.joylax.wordpress.com

  9. April 10, 2012 at 7:30 am

    Great arcticle, with clear, concise code

  10. May 14, 2012 at 7:01 am

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

  11. John
    August 9, 2012 at 5:21 am

    Awesome!!! Great Tutorial! Really helped and very comprehensive, nothing missing unlike most tuts.

  12. vish
    September 13, 2012 at 6:01 pm

    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]);

    • September 19, 2012 at 12:54 pm

      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.

  13. lars
    September 21, 2012 at 11:47 am

    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?/

    • September 21, 2012 at 2:44 pm

      The BaseAdapter class is built in the Android API.
      Prior using it, just make sure you have imported it:

      import android.widget.BaseAdapter;
      
  14. lars
    September 24, 2012 at 9:34 am

    can you maybe just send me your code? because i keep having errors

  15. December 18, 2012 at 9:13 am

    Thank you for every other informative site. The place else may I am getting that kind of info written in such an ideal approach?

    I have a undertaking that I’m simply now operating on, and I’ve been at
    the glance out for such information.

  16. Neddy
    December 29, 2012 at 4:01 pm

    what happens when i need to use different colors?

    • December 29, 2012 at 4:20 pm

      Change the values of “int[] color” array to your desired colors.

  17. January 7, 2013 at 8:32 pm

    Helpful info. Lucky me I discovered your web site by accident,
    and I am surprised why this coincidence didn’t came about earlier! I bookmarked it.

  18. April 15, 2013 at 8:24 pm

    enda głosiła, wkurzywszy się
    przeraźliwie, samodzielnie obfity skała http://www.
    palmspringsca.gov dookoła kościoła trzykroć przetoczył.
    Tak, gigancie owo gród, pomyślał sir Roger, skoro
    takich herosów nadziać się tu jest dozwolone.

  19. June 16, 2014 at 9:31 am

    Building a Cսstom Fancy ListView in Android

  20. smriti
    August 4, 2014 at 5:21 pm

    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

  1. May 4, 2012 at 9:09 pm
  2. May 23, 2012 at 2:39 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 517 other followers

%d bloggers like this: