Android Custom ListView Tutorial


Almost all Android apps uses ListView – showing list of records, settings, songs, articles, and many other types of data a certain app can handle. An Android ListView is simply a vertically scrollable list of items.This tutorial will show you how to create a customized row in your ListView (with image and text). This is probably the simplest android ListView tutorial on the internet. Haha!
I remember using a ListView when I have to list records of location with its thumbnail, location name and date the data were taken.

Upper part of our ListView
Upper part of our ListView

Anyway, we are going to have Folders as our items on the list. Our code will have the following capability:

  • Include custom folder icon, folder name and description for each list item.
  • Show a toast when a user clicks on an item on the list (means we’re going to have an onClickListener)

Code Download

You can download the code here: (If you’re not familiar with Google Drive, you have to click on File > Download to download the code)
Download Code

Files Needed

We are going to need only 2 JAVA files, 2 XML files and 3 custom icons.

Highlighted are the files we’ll create.
Highlighted are the files we’ll create.

Let’s Code!

activity_main.xml – Contains our ListView.

<?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:background="#FFFFFF"
    android:orientation="vertical" >

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

</LinearLayout>

listview_item_row.xml – the layout of each list item in our list view.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp" >

    <ImageView
        android:id="@+id/imageViewFolderIcon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:paddingRight="10dp"
        android:src="@drawable/folder" />

    <TextView
        android:id="@+id/textViewFolderName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/imageViewFolderIcon"
        android:text="Folder name here."
        android:textSize="20dp" />

    <TextView
        android:id="@+id/textViewFolderDescription"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textViewFolderName"
        android:layout_toRightOf="@+id/imageViewFolderIcon"
        android:text="Folder description here."
        android:textColor="#c5c5c5"
        android:textSize="14dp" />

</RelativeLayout>

It will look like this:

android-listview-tutorial-listiem-layout

-Folder Icon
android:id=”@+id/imageViewFolderIcon”
android:layout_alignParentLeft=”true”
android:layout_alignParentTop=”true”

-Folder Name
android:id=”@+id/textViewFolderName”
android:layout_alignParentTop=”true”
android:layout_toRightOf=”@+id/imageViewFolderIcon”

-Folder Description
android:id=”@+id/textViewFolderDescription”
android:layout_below=”@+id/textViewFolderName”
android:layout_toRightOf=”@+id/imageViewFolderIcon”

MainActivity.java – We have two classes in this file, first is the MainActivity where we set each of our list item data and second is the small Folder class that will take care of our list item data such as the folderIcon, folderName and folderDescription.

package com.example.androidlistview;

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

public class MainActivity extends Activity {

    private ListView listViewArticles;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        
         // Data can be from your database. You have to know the number of list
         // items in advanced, in our example, we have 9
         
         
        Folder[] folderData = new Folder[27];

        
         // @always start with index 0
          
          // @9 items in our list view.
         

        folderData[0] = new Folder(R.drawable.icon_music_folder, "Usher", "My most favorite Usher songs.");
        folderData[1] = new Folder(R.drawable.icon_pictures_folder, "Family Images", "Pictures from different occasions.");
        folderData[2] = new Folder(R.drawable.icon_spreadsheet_folder, "Budget Spreadsheet", "My budget record every week.");
        folderData[3] = new Folder(R.drawable.icon_music_folder, "FM Static", "One of my most favorite bands.");
        folderData[4] = new Folder(R.drawable.icon_pictures_folder, "Outing - 2012", "Pictures in Boracay Island.");
        folderData[5] = new Folder(R.drawable.icon_spreadsheet_folder, "Business Spreadsheet", "Business accounts record.");
        folderData[6] = new Folder(R.drawable.icon_music_folder, "New Artists", "Cool songs by new artists.");
        folderData[7] = new Folder(R.drawable.icon_pictures_folder, "Anniversary - 2012", "Company party.");
        folderData[8] = new Folder(R.drawable.icon_spreadsheet_folder, "Credit Spreadsheet", "Credit records every month.");

        folderData[9] = new Folder(R.drawable.icon_music_folder, "Usher - 2", "My most favorite Usher songs - 2.");
        folderData[10] = new Folder(R.drawable.icon_pictures_folder, "Family Images - 2", "Pictures from different occasions - 2.");
        folderData[11] = new Folder(R.drawable.icon_spreadsheet_folder, "Budget Spreadsheet - 2", "My budget record every week - 2.");
        folderData[12] = new Folder(R.drawable.icon_music_folder, "FM Static - 2", "One of my most favorite bands - 2.");
        folderData[13] = new Folder(R.drawable.icon_pictures_folder, "Outing - 2012 - 2", "Pictures in Boracay Island - 2.");
        folderData[14] = new Folder(R.drawable.icon_spreadsheet_folder, "Business Spreadsheet - 2", "Business accounts record - 2.");
        folderData[15] = new Folder(R.drawable.icon_music_folder, "New Artists - 2", "Cool songs by new artists - 2.");
        folderData[16] = new Folder(R.drawable.icon_pictures_folder, "Anniversary - 2012 - 2", "Company party - 2.");
        folderData[17] = new Folder(R.drawable.icon_spreadsheet_folder, "Credit Spreadsheet - 2", "Credit records every month - 2.");
        
        folderData[18] = new Folder(R.drawable.icon_music_folder, "Usher - 3", "My most favorite Usher songs - 3.");
        folderData[19] = new Folder(R.drawable.icon_pictures_folder, "Family Images - 3", "Pictures from different occasions - 3.");
        folderData[20] = new Folder(R.drawable.icon_spreadsheet_folder, "Budget Spreadsheet - 3", "My budget record every week - 3.");
        folderData[21] = new Folder(R.drawable.icon_music_folder, "FM Static - 3", "One of my most favorite bands - 3.");
        folderData[22] = new Folder(R.drawable.icon_pictures_folder, "Outing - 2012 -3", "Pictures in Boracay Island - 3.");
        folderData[23] = new Folder(R.drawable.icon_spreadsheet_folder, "Business Spreadsheet - 3", "Business accounts record - 3.");
        folderData[24] = new Folder(R.drawable.icon_music_folder, "New Artists - 3", "Cool songs by new artists - 3.");
        folderData[25] = new Folder(R.drawable.icon_pictures_folder, "Anniversary - 2012 - 3", "Company party - 3.");
        folderData[26] = new Folder(R.drawable.icon_spreadsheet_folder, "Credit Spreadsheet - 3", "Credit records every month - 3.");
        
        // Pass the folderData to our ListView adapter 
        FolderAdapter adapter = new FolderAdapter(this,
                R.layout.listview_item_row, folderData);

        // Set the adapter to our ListView
        listViewArticles = (ListView) findViewById(R.id.listView1);
        listViewArticles.setAdapter(adapter);

        
        // ListView item click listener. So we'll have the do stuff on click of
        // our ListItem
         
        listViewArticles.setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {

                // get the clicked folder name
                String listItemText = ((TextView) view
                        .findViewById(R.id.textViewFolderName))
                        .getText()
                        .toString();

                // just toast it
                Toast.makeText(MainActivity.this,
                        "You clicked: " + listItemText, Toast.LENGTH_LONG)
                        .show();

                // if you want to show a new screen or activity, you can call the intent here
            }
        });
    }

    
    // You can put this in another java file. This will hold the data elements
    // of our list item.
    
    class Folder {

        public int folderIcon;
        public String folderName;
        public String folderDescription;

        // Constructor.
        public Folder(int folderIcon, String folderName,
                String folderDescription) {

            this.folderIcon = folderIcon;
            this.folderName = folderName;
            this.folderDescription = folderDescription;
        }
    }
}

FolderAdapter.java – This file will make the list items come true. We’ll override the getView to set our customized data.

package com.example.androidlistview;

import com.example.androidlistview.MainActivity.Folder;

import android.app.Activity;
import android.content.Context;
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 FolderAdapter extends ArrayAdapter<Folder> {

    Context mContext;
    int layoutResourceId;
    Folder data[] = null;

   
     // @mContext - app context
      
     // @layoutResourceId - the listview_item_row.xml
      
     // @data - the ListItem data
     
    public FolderAdapter(Context mContext, int layoutResourceId, Folder[] data) {

        super(mContext, layoutResourceId, data);
        this.layoutResourceId = layoutResourceId;
        this.mContext = mContext;
        this.data = data;
    }

    
     // @We'll overried the getView method which is called for every ListItem we have.
      
     // @There are lots of different caching techniques for Android ListView to
     // achieve better performace especially if you are going to have a very long ListView.
      
     // @convertView - the cache of list item row layout, if it is null, inflate new
     
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if(convertView==null){
            // inflate the listview_item_row.xml parent
            LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
            convertView = inflater.inflate(layoutResourceId, parent, false);
        }
        
        // get the elements in the layout
        ImageView imageViewFolderIcon = (ImageView) convertView.findViewById(R.id.imageViewFolderIcon);
        TextView textViewFolderName = (TextView) convertView.findViewById(R.id.textViewFolderName);
        TextView textViewFolderDescription = (TextView) convertView.findViewById(R.id.textViewFolderDescription);

        
        // Set the data for the list item. You can also set tags here if you want.
         
        Folder folder = data[position];

        imageViewFolderIcon.setImageResource(folder.folderIcon);
        textViewFolderName.setText(folder.folderName);
        textViewFolderDescription.setText(folder.folderDescription);

        return convertView;
    }

}

Output Screenshots

Lower part of our ListView
Lower part of our ListView

When user clicks on an item “Budget Spreadsheet”
When user clicks on an item
“Budget Spreadsheet”

Further Readings

If you’re loading your images from the internet, you might want to lazy load them for better ListView performance. You can use a library called LazyList.

If you want to see code example which focuses a bit on the adapter, see this post: Android ListView with Adapter Example

Thanks for reading this Android Custom ListView Tutorial!


2 responses to “Android Custom ListView Tutorial”

Leave a Reply

Your email address will not be published. Required fields are marked *