public class ViewHolder {
// I added a generic return type to reduce the casting noise in client code
@SuppressWarnings("unchecked")
public static <T extends View> T get(View view, int id) {
SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
if (viewHolder == null) {
viewHolder = new SparseArray<View>();
view.setTag(viewHolder);
}
View childView = viewHolder.get(id);
if (childView == null) {
childView = view.findViewById(id);
viewHolder.put(id, childView);
}
return (T) childView;
}
}
一个ListView使用的好坏全都依赖于Adapter的实现,Adapter为ListView提供数据源,并渲染View。以下我们来分析一下,一个好的Adapter应该如何实现。首先,看这个例子:
代码量很少。我们来一下其
getView
方法,每一次在渲染一个Item
的时候,便会加载一次list_item
这个布局文件,由此可见,效率是很低的。 于是针对getView
作如下改进:显然,这样一改进了之后,只会在convertView不存在的情况下,才会去渲染一个新的,如果之前存在过,就采用之前的。这样下来。比如一个ListView中有100条记录,但屏幕上同时只能显示10个,系统则只需要构造10个convertView就可以了。通过看打印出来的Log,便可以证实这一点。
第一个可以优化的地方已经被我们优化了。接着还是看
getView
这个方法,还有一个可以优化的地方便是findViewById()
这个方法的使用。在Android源码中,findViewById()
这个方法的实现如下:由此可以,对某一个View调用其findViewById()方法,便会遍历这个View中的所有子元素进行查找,这也是一种非常耗时的操作。接着,我们便对这个问题进行优化。 接着便出现了
ViewHolder
这个思路了。其思路在于,当我们已经通过findViewById()
这个方法获得View
之后,便将这个View
存到一个ViewHolder
的对象中。下次使用时,直接从ViewHolder
对象中取。优化后的代码如下:其它的关于Adapter优化的思路。在文章一和文章二中提到了另外一种方式:
个人觉得,在Adapter中采用这种方式,只能说是优化代码的结构,并不能优化效率。同时,也会增加代码的复杂度。 最后这个Adapter的代码如下: