I was reading an article over on charlie.collins’s blog about using a ViewHolder class to cache the results of a findViewById() when used inside the getView() of a list’s adapter. I gave his recommendation a try and I did notice a speed improvement in my app so the observation that findViewById() is a performance hit has enough merit to go out of your way to enable some kind of caching mechanism.
While Charlie went the route of creating a class to hold the various views he was interested in, I decided to take a slightly different approach and make use of the alternative setTag(int, Object) function instead.
protected Object getViewHandle(View aParentView, int aViewToFind) { Object v = aParentView.getTag(aViewToFind); if (v==null) { v = aParentView.findViewById(aViewToFind); aParentView.setTag(aViewToFind,v); } return v; }
I would use this getViewHandle() function in the list’s adapter in following way:
@Override public View getView(int position, View convertView, ViewGroup parent) { View theItemView = convertView; if (theItemView==null) { theItemView = ((LayoutInflater)getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.my_item_layout,null); } TextView tv = (TextView)getViewHandle(theItemView,R.id.some_text_view); ... }
A downside to this technique is that it is only available in API 4+ (2.0+).
If you need to work with Android pre-2.0, a drop-in replacement to the getViewHandle() function would be similar to this one:
class ViewCacher {
protected HashMap<Integer,View> mCache = new HashMap<Integer,View>();
public View getViewHandle(View aParentView, Integer aViewToFind) {
View v = mCache.get(aViewToFind);
if (v==null) {
v = aParentView.findViewById(aViewToFind);
mCache.put(aViewToFind,v);
}
return v;
}
}
protected View getViewHandle(View aParentView, int aViewToFind) {
ViewCacher vc = (ViewCacher)aParentView.getTag();
if (vc==null) {
vc = new ViewCacher();
aParentView.setTag(vc);
}
return vc.getViewHandle(aParentView, aViewToFind);
}{/java]
- On Thursday, June 16, 2011, xjaphx asked the question…
- Hi, Code Monkey, I’ve just got a little wondering how you could measure the ViewHolder pattern performance in order to prove that it’s better than regular calling findViewById() for each getView() callbacks?
UCM responds: My proof is a bit too complex to place here, so I created a new blog post that explains it.
Leave a Reply