Android: Creating Custom ListView for Beginners

After you get your hands on Android, you will find the most useful widget is the ListView. You may also feel that it’s required on every activity. Android being Open-Source, it is the most flexible mobile platform out there. Everyone, wants to customize it according to their taste. You would hardly see an app that uses the default look and feel of the widgets. But with flexibility comes complexity.
You can judge the importance of the ListView widget by the fact that there was a complete session in Google I/O on ListViews. A ListView can take any shape from a colorful contact list in whatsapp to a text filled tweet in twitter.

Unlike other tutorials, I want this article to be more general and I would try my best so that you can create a listview according to your needs rather than just a custom listview developed in this article.

By default android renders only a single TextView in each of the ListView’s row and binds string data through an adapter. But you can customize the ListView’s row and place your own widget items in it and then bind data through your own custom adapter.

First create a simple layout and declare a ListView in it. You can also place other components in this layout if you want, like a TextView to give some heading or information.
main.xml

 

Now we will create the layout for listview row. This will be the layout in which you can customize your list row. This will be re-inflated every time a new entry is made to the listview. The widgets in this layout will depend on your requirement, like if you are developing a contact list then you will only need a ImageView and TextView or if you are developing a songs list then you might consider adding another TextView for the artist name apart from album icon and album name.

For this tutorial I made something like a message app which includes a ImageView and 4 TextViews in each list item. Here is the xml layout for the same.

list_item_message.xml

 

Now we will create a simple class that would help us in binding data and getting the reference to a particular component’s value in each row.

       public class MessageDetails {
            int icon ;
            String from;
            String sub;
            String desc;
            String time;

            public String getName() {

                return from;
            }

            public void setName(String from) {

                this.from = from;
            }

            public String getSub() {

                return sub;
            }

            public void setSub(String sub) {

                this.sub = sub;
            }

            public int getIcon() {
                return icon;
            }

            public void setIcon(int icon) {

                this.icon = icon;
            }

            public String getTime() {
                return time;
            }

            public void setTime(String time) {

                this.time = time;
            }

            public String getDesc() {
                return desc;
            }

            public void setDesc(String desc) {

                this.desc = desc;
            }
        }

Next up is the brain of our ListView, yes our very own Custom Adapter.

 

Our custom adapter takes in a ArrayList of our MessageDetails class and a context as parameters. You can easily notice that all the work is done by the getView method which is called every time a list item is instantiated.
It returns a View corresponding to the data at the specified position. Here ViewGroup is the parentView i.e the ListView. We check if the convertView is not null which helps android to re-use the old View and reduce battery consumption.
I have used app’s icon as the image for all my list item but you can use your own algorithm.

Now we are ready with the setup, we just need to fill our data into the ListView. So here’s the onCreatemethod:

public class Messages extends Activity {
ListView msgList;
ArrayList<MessageDetails> details;
AdapterView.AdapterContextMenuInfo info;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

msgList = (ListView) findViewById(R.id.MessageList);

details = new ArrayList<MessageDetails>();

MessageDetails Detail;
Detail = new MessageDetails();
Detail.setIcon(R.drawable.ic_launcher);
Detail.setName(“Bob”);
Detail.setSub(“Dinner”);
Detail.setDesc(“Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla auctor.”);
Detail.setTime(“12/12/2012 12:12”);
details.add(Detail);

Detail = new MessageDetails();
Detail.setIcon(R.drawable.ic_launcher);
Detail.setName(“Rob”);
Detail.setSub(“Party”);
Detail.setDesc(“Dolor sit amet, consectetur adipiscing elit. Nulla auctor.”);
Detail.setTime(“13/12/2012 10:12”);
details.add(Detail);

Detail = new MessageDetails();
Detail.setIcon(R.drawable.ic_launcher);
Detail.setName(“Mike”);
Detail.setSub(“Mail”);
Detail.setDesc(“Lorem ipsum dolor sit amet, consectetur adipiscing elit.”);
Detail.setTime(“13/12/2012 02:12”);
details.add(Detail);

msgList.setAdapter(new CustomAdapter(details , this));
}

So, here we are with our very own custom listview, piece of cake naa?

Cool?

Now when you have your own ListView you may also want to add some functionality to it like a context menu and click listeners.

Context Menu:
First, register your ListView for context menu on onCreate.

registerForContextMenu(msgList);

and here is the onCreateContextMenu and onContextItemSelected.

 

 

Context Menu

List Item Click listener:
For having a item click listener on your lisview you have to add the following lines to each of your widget in the list_item_message.xml.

android:focusable=”false”
            android:focusableInTouchMode=”false”

Here’s the click listener:

 

 

Item Click Listener

We retrieve the text in the ‘From TextView ‘ by this line (String) ((TextView) v.findViewById(R.id.From)).getText(); which you can also retrieve through this code: details.get(position).getName().

Click Listener for a specific component:
You can also have click listener for a specific widget. For this tutorial, I have implemented it on the ImageView which made the most sense. Click listener for a widget has to be added on the getView method in our Custom Adapter. So here’s is the modified getView method. Notice you have to declare the int position as final.

 

 

ImageView Click Listener

I hope I helped you in making your own custom ListView. Please Comment if you have any query and remember sharing is caring!

[UPDATE]
The thing you asked the most in comments – here’s the link to download the whole Eclipse Project. Hope this will clear all your doubts and issues if faced any.

Don’t forget to like ThePCWizard on Facebook for latest tech news, geeky discussions and best of tech trolls. Also subscribe to RSS feeds and YouTube channel for being updated with the latest tech tutorials.

 

49 thoughts on “Android: Creating Custom ListView for Beginners”

  1. Hi,
    on the first screenshot (twitter app), there is a dropdown menu on the right of each item, do you know how to implement that?
    great tutorial by the way

  2. Hi, I am starting to learn android dev, and this is a nice tutorial but the last addition to custom addapter is giving me many errors, maybe I place it wrongly?

    Thank you very much for this tutorial it shows many concepts

    descView.setText(msg.desc);
    timeView.setText(msg.time);
    //error from here
    @Override
    image.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
    // TODO Auto-generated method stub
    AlertDialog.Builder adb=new AlertDialog.Builder(Messages.this);
    adb.setMessage("Add To Contacts?");
    adb.setNegativeButton("Cancel", null);
    final int selectedid = position;
    final String itemname= (String) _data.get(position).getName();

    adb.setPositiveButton("OK", new AlertDialog.OnClickListener() {
    public void onClick(DialogInterface dialog, int which) {

    //Your working
    }});

    adb.show();
    }
    });

    return v;
    }

  3. Thanks for this fantastic help~~~. Finally my project can continue…cheers!! simply the best so far for listview

  4. Can i download your code?
    so sory i'm a dummy beginer, i found many error i can't understand… please let me download your project.. thanks for the great tutorial…

  5. dude i tried ur code n it had almost only 1 or 2 bugs (dats great). But when i run it on my device (android 4.2) it doesnt display any content on the main page. Just a white space 🙁
    please help me out. I am working on a project n need help very soon. Thank. Nice Blog 🙂

  6. hi,

    thanks for your post…can u tel me,How to use setonclicklisterner in Listview for changing text in textview?

  7. in onclick event of list item i want to delete a row & want to update list without getting being scrolled to 1st row. how to do this? please help

  8. Thank you sir, this really is a nice tutorial. I understood how to create custom list views in more simple terms.

    Slightly to make it complex, I would like to have a check box to each of the messages in the list and then have a actionbar menu to delete those selected. Could you help me on this?

    ~Kiran

  9. Thanks Dude , i was messing around from so long with this Custom List View.. and you are a Savior . !!!
    Thanks for the Tutorial and for CODE . !!!!
    – Vinay

  10. I'm Getting NullPointerException at

    v = vi.inflate(R.layout.list_item_message, null);

    Can you please help me

  11. I have put imageview in getView Method class that extends from BaseAdapter class and i am getting image name from database and i need to get bitmap image from assets folder and then set in imageview.setImageBitmap for that reason i have made one function
    private Bitmap getBitmapFromAsset(String strName) {
    AssetManager assetManager = getAssets();
    InputStream istr = null;
    Bitmap bitmap = null;

    try {
    istr = assetManager.open(strName);
    if(istr == null)
    {
    Log.i("getBitmapFromAsset isStr",""+istr);
    bitmap = BitmapFactory.decodeStream(assetManager.open("save_fatwa.jpg"));
    }
    else
    {
    bitmap = BitmapFactory.decodeStream(istr);
    }
    } catch (Exception e) {
    Log.i("getBitmapFromAsset",""+bitmap);
    e.printStackTrace();
    }

    return bitmap;
    }
    when i am writing this function inside CustomAdapter class i am getting error at getAssets() line by indicating that this function is not applicable for this class what can i do ?

Leave a Comment

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