Over a million developers have joined DZone.

Android ListView Optimizations Part 1: The ViewHolder

The role of the adapter is to provide views to the list.

· Mobile Zone

When you develop on Android, you will probably need to make lists pretty quickly. However, it can be complicated to understand all the mechanisms when you are a beginner. This series of posts aims to give you tips if you want to increase the smoothness of your lists.

This first post is a basic one which talks about a well known tip, called ViewHolder. This is absolutely essential if you want to have a viable list. But we must first understand how it works.

A list is composed of elements displayed in views; which ones are declared in XML files (generally). Usually, a list is composed of elements whose views are the same, only the content changes. That’s why we use the same view for all the elements. The role of the adapter is to provide views to the list. It has to create and modify their contents.

Here is an example of a basic custom adapter, providing elements with a name and a description:

public class MyAdapter extends BaseAdapter {

    private LayoutInflater mLayoutInflater;
    private List mData;

    public MyAdapter(Context context, List data){
        mData = data;
        mLayoutInflater = LayoutInflater.from(context);

    public int getCount() {
        return mData == null ?  : mData.size();

    public MyPojo getItem(int position) {
        return mData.get(position);

    public long getItemId(int position) {
        return position;

    public View getView(int position, View view, ViewGroup parent) {

        //This is bad, do not do this at home
        View vi = mLayoutInflater.inflate(R.layout.item, parent, false);

        TextView tvName = (TextView) vi.findViewById(R.id.textView_item_name);
        TextView tvDescription = (TextView) vi.findViewById(R.id.textView_item_description);

        MyPojo item = getItem(position);


        return vi;

That is the code we could make when we don’t know that listviews recycle their views. Indeed, when you scroll down, the views disappearing on the top are reused to display items on the bottom of your list. I hope that this is clear because it’s very important :p. As a consequence, we will tag our views in order to avoid inflating views that already exist (this operation takes a long time).

We will write a class (called ViewHolder) in which references between the widgets will be saved:

static class ViewHolder{
    TextView tvName;
    TextView tvDescription;

And the adapter:

public View getView(int position, View view, ViewGroup parent) {

  View vi = view;             //trying to reuse a recycled view
  ViewHolder holder = null;

  if (vi == null) {
      //The view is not a recycled one: we have to inflate
      vi = mLayoutInflater.inflate(R.layout.item, parent, false);
      holder = new ViewHolder();

      holder.tvName = (TextView) vi.findViewById(R.id.textView_item_name);
      holder.tvDescription = (TextView) vi.findViewById(R.id.textView_item_description);
  } else {
      // View recycled !
      // no need to inflate
      // no need to findViews by id
      holder = (ViewHolder) vi.getTag();

  MyPojo item = getItem(position);


  return vi;

If you want to add other widgets in your elements (an image for example), you will have to add them in the ViewHolder too.

That’s all - I’ll talk next time about the way you can optimize your images in your lists (LRUCache, etc.).

java,mobile,architecture,tips and tricks,tools & methods

Published at DZone with permission of Antoine Merle, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}