What is the benefit of ViewHolder pattern in android?

android, android-arrayadapter, android-viewholder, listview

Solution

Understand how listview recycling works

How ListView's recycling mechanism works

You cannot recycle a row that is presently in use. The above link explains how listview recycling mechanism works

So What is the benefit of using ViewHolder?

Quoting docs

Your code might call `findViewById()` frequently during the scrolling of ListView, which can slow down performance. Even when the Adapter returns an inflated view for recycling, you still need to look up the elements and update them. A way around repeated use of `findViewById()` is to use the "view holder" design pattern.

    public View getView(int position, View convertView, ViewGroup parent) { 
             ViewHolder holder; 

             if (convertView == null) { // if convertView is null
                 convertView = mInflater.inflate(R.layout.mylayout, 
                         parent, false);
                 holder = new ViewHolder(); 
                     // initialize views  
                convertView.setTag(holder);  // set tag on view
            } else { 
                holder = (ViewHolder) convertView.getTag();
                        // if not null get tag 
                        // no need to initialize
            } 

            //update views here  
            return convertView; 
    }

You missed the important part `convertView.setTag(holder)` and `holder = (ViewHolder) ConvertView.getTag()`

http://developer.android.com/training/improving-layouts/smooth-scrolling.html

Problem

When you are developing an Android program; and you want to have a ArrayAdapter you can Simply have a Class (most of times with ViewHolder suffix) or directly inflate your convertView and find your view by id. So What is the benefit of using ViewHolder? The example of both here : ``` @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = ((Activity)getContext()).getLayoutInflater().inflate(R.layout.row_phrase, null); } ((TextView) convertView.findViewById(R.id.txtPhrase)).setText("Phrase 01"); } ``` Or create an inner class in the ArrayAdapter as following: ``` static class ViewHolder { ImageView leftIcon; TextView upperLabel; TextView lowerLabel; } ``` and finally in the getView : ``` @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (view == null) { view = LayoutInflater.from(context).inflate(R.layout.row_layout, null, false); holder = new ViewHolder(); holder.leftIcon = (ImageView) view.findViewById(R.id.leftIcon); } } ```

Original source

Related problems