Home > Design Patterns > ViewHolder Pattern – Caching View Efficiently

ViewHolder Pattern – Caching View Efficiently


A – Yeah! It works!

Yo, we’ve got a list view to display something:

Sample ListView

Sample ListView

This is what people like to write for list adapter:

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {

		View v = convertView;
		if(v == null) {
			LayoutInflater inflater = LayoutInflater.from(mContext);
			v = inflater.inflate(R.layout.layout_list_item, null);
		}

		TextView txtName = (TextView)v.findViewById(R.id.txtName);
		TextView txtMail = (TextView)v.findViewById(R.id.txtMail);

		Contact entry = mList.get(position);

		txtName.setText(entry.getName());
		txtMail.setText(entry.getMail());

		return v;
	}

That’s great because it works with no problem and the list displays contents nicely!!!

 

B – Dig It Out

Let’s see how it works..

+ First time loaded, oh right, it’s null!  Ok, to find our TextView controls, ‘findViewById()‘ is loaded. Great, we’ve got it!

+ Second time loaded,  it must be not null, but ‘findViewById()‘ is loaded. Well, just one time, it’s fine!

+ Next time loaded, it’s absolutely not null, eh, ‘findViewById()‘ is called by default. Eh oh..

+ ……whatever time

+ xxx th time…..something is calling ‘findViewById()‘…so stupid, damn it! But it’s still running fine … _ _!

 

C – Giving birth to a child: ViewHolder

You may see the problem, too. When the list is too big, containing lots of rows, then the calling of ‘findViewById()‘ everytime will impact slightly to your application performance, even though, it’s still working fine; however, it’s quite risky since it might be dead at some unexpected point.

This is one of most common problem, it is! Hence, from somewhere, the idea of ViewHolder pattern was created to improve this current situation.

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View v = convertView;
		if(v == null) {
			LayoutInflater inflater = LayoutInflater.from(mContext);
			v = inflater.inflate(R.layout.layout_list_item, null);
			ViewHolder holder = new ViewHolder();
			holder.txtName = (TextView)v.findViewById(R.id.txtName);
			holder.txtMail = (TextView)v.findViewById(R.id.txtMail);
			v.setTag(holder);
		}

		Contact entry = mList.get(position);
		if(entry != null) {
			ViewHolder holder = (ViewHolder)v.getTag();
			holder.txtName.setText(entry.getName());
			holder.txtMail.setText(entry.getMail());
		}
		return v;

	}

	static class ViewHolder {
		TextView txtName;
		TextView txtMail;
	}

The ViewHolder object is static, once created, it will cache all things inside. Therefore, we can avoid calling ‘findViewById()‘ on resource everytime.

 

D – Note

- Something works doesn’t mean it’s the best. Even if it’s fine, it might contain some invisible problems.

- Use ViewHolder pattern whenever possible to cache data!

 

E – Final Words

- Just something I’ve learned and wanna share to everyone.

- Feel free to comment, suggest and request; I’m here to listen to everyone’s voice :)

- Free to share, free to take!

 

Cheers,

Pete Houston

About these ads
  1. October 14, 2014 at 1:20 am

    Hi there! Your webpage is running slow , this kind of consumed like a minute or two to
    actually load up, I actually have no idea if it is just me or your blog on the other hand google
    worked acceptable for me. However , I appreciate you for submitting awesome article.
    Everyone who actually discovered this site should have noticed this particular article
    incredibly valuable. I hope I’ll be able to find even more incredible information and I really should
    flatter your site simply by saying you have done good work.
    Right after checking out your post, I’ve book-marked your site.

  2. Nirmal
    June 12, 2014 at 8:56 pm

    you are so great ,,,thank you

  3. May 7, 2014 at 12:53 am

    Nice post! I would like to see how to implement the ViewHolder pattern when you are using some dependence injection framework like aQuery. Does anyone has some clue on what changes?

  4. January 6, 2013 at 10:29 pm

    I made a tool to automatically generate code for a ViewHolder given an XML Layout. Check it out here: http://www.buzzingandroid.com/tools/android-layout-finder/

  5. vault
    September 13, 2012 at 4:33 pm

    Is this ViewHolder really useful and are its improvements really impacting performance? Is findViewById so resource-consuming? I don’t see any benefit at the moment…

  6. gropapa
    February 24, 2012 at 3:45 pm

    so actually if i have a custom ViewGroup like
    com.mystuff.MyViewGroup extends LinearLayout
    with the same variables you declared in your example…
    i don’t need to to use the viewholder pattern? like

    void MyViewGroup (){
    txtName = (TextView)v.findViewById(R.id.txtName);

    }

    • February 27, 2012 at 2:15 pm

      Yes, you still need ViewHolder pattern. YourViewGroup is just an extended View no more no less. Always refer or keep your stuffs `static` somewhere to be resided in memory for cache.

  7. gropapa
    February 15, 2012 at 6:46 am

    what if the view is a custom view (group) that stores the datamodel itself, is it ok just to add the view to the viewHolder (the view can retain the references to its children)
    for instance i have a customlinearLayout class that has a chackbox and a textview, in the constructor i already do a findViewById() and get the datamodel…so storing the whole view in the ViewHolder seems to be ok…isn’t it?

    • February 24, 2012 at 10:22 am

      Yes, it’s ok, no problem at all.

  8. December 30, 2011 at 10:47 am

    I am getting an error on Contact entry = mList.get(position); It tells me that Contact cannot be resolved as a type.

    And..

    holder.txtName = (TextView)v.findViewById(R.id.txtName);
    holder.txtMail = (TextView)v.findViewById(R.id.txtMail); //error on the TextView here

    I’ve been working on this for a while and i really cant figure it out… I’m sure its somethings small that im overlooking im still pretty new at this concept. Thanks in advanced

    • December 30, 2011 at 10:57 am

      I FIGURED IT OUT!!!! IT was a newbie mistake.. THANKS FOR THE TUTORIAL!!!

    • mahsanq
      October 16, 2012 at 5:53 pm

      whats was the issue with Contact i am having the same issue. i just started development on android so i am pretty new to this stuff.

  9. September 21, 2011 at 11:07 am

    So great! Thanks a lot
    Very useful with me ^^

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: