Efficient ListView’s in Android: View Holder Pattern
When we’re going to implement a good adapter, we have to take into account two things: reuse the convertView parameter and
variable of the getView() method to avoid inflating new View objects when it’s not needed.
To solve this you must use the ViewHolder pattern, which is what we’re going to explain in this little article
Not taking into account those advices may cause, sooner or later, the following findViewById() calls to provoke performance problems. This could be solved with the View Holder pattern.
To apply this pattern, we could simply create a nested class into the adapter that we’re using for the ListViews’ rows.
For example, if each of these rows contains 3 TextView (as we saw in the example: RESTFul app), we should include the class into ContactsArrayAdapter class
static class ContactsViewHolder {
TextView txName;
TextView txEmails;
TextView txPhones
}
For the getView() method we have to make modifications. We’ve decided to separate the ContactsArrayAdapter class in a new file:
package es.jmanzano.json;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
/**
* Adapter class to show the contacts
*/
public class ContactsArrayAdapter extends ArrayAdapter {
/** Contacts list */
private List contacts;
/** Context */
private Context context;
public ContactsArrayAdapter(Context context, int textViewResourceId,
List contacts) {
super(context, textViewResourceId, contacts);
this.context = context;
this.contacts = contacts;
}
@Override
public View getView(int position, View v, ViewGroup parent) {
// Keeps reference to avoid future findViewById()
ContactsViewHolder viewHolder;
if (v == null) {
LayoutInflater li = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
v = li.inflate(R.layout.contact_row, parent, false);
viewHolder = new ContactsViewHolder();
viewHolder.txName = (TextView) v.findViewById(R.id.tvName);
viewHolder.txEmails = (TextView) v.findViewById(R.id.tvEmails);
viewHolder.txPhones = (TextView) v.findViewById(R.id.tvNumbers);
v.setTag(viewHolder);
} else {
viewHolder = (ContactsViewHolder) v.getTag();
}
Contact contact = contacts.get(position);
if (contact != null) {
viewHolder.txName.setText(contact.getName());
viewHolder.txEmails.setText(contact.getEmails().toString());
viewHolder.txPhones.setText(contact.getNumbers().toString());
}
return v;
}
static class ContactsViewHolder {
TextView txName;
TextView txEmails;
TextView txPhones;
}
}
Here we can see how to use the setTag() method to set and get the ContactsViewHolder. This will manage all the visual data in our ListView and, as we can see, we can avoid the performance problem findViewById() due to we’re reusing the views thanks to ContactsViewHolder.

More efficient and informative example for Android ListView: http://www.technotalkative.com/category/android/listview/
Pingback: TextView Wrap Performance Problem - Android-Hilfe.de
Autogeneration of ViewHolder code from XML Layout: Android Layout Finder | Buzzing Android
Pingback: How to stop list recycling On Scroll of list View, in a custom cursor adapter android : Android Community - For Application Development
Pingback: Large set of data in listview crashing the android app : Android Community - For Application Development
Pingback: Changing elements at the top of an Adapter without repositioning lower items : Android Community - For Application Development