深入理解ViewHolder
ListView和GridView应该是我们Android开发中最常见的控件了,我们几乎每天都需要和他们打交道。
作为最常见的信息展示布局,我们每次使用都会进行一下几步,建立Adapter,设置getView() getCount()方法等等。
getView()在Adapter数据和我们的视图文件之间建立关系,是最重要的方法。
常见的写法
利用Android的Recycler机制,利用convertView来重新回收View,效率有了本质提高。View的每次创建是比较耗时的,因此对于getview方法传入的convertView应充分利用 != null的判断 。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v;
Log.i(TAG, "getView()" + position);
if (convertView == null) {
// 若为空,则动态加载一个View
v = inflater.inflate(R.layout.list_item, null);
} else {
v = convertView;
}
mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader);
TextView mTextView = (TextView) v.findViewById(R.id.item_text);
mTextView.append("------>" + position);
return v;
}*/
}
ViewHolder
ViewHolder将需要缓存的view封装好,convertView的setTag才是将这些缓存起来供下次调用。 当你的listview里布局多样化的时候 viewholder的作用体现明显,效率再一次提高。 View的findViewById()方法也是比较耗时的,因此需要考虑只调用一次,之后就用View.getTag()方法来获得ViewHolder对象。
最重要的就是减少了findViewById()方法的调用,保证可以重用的convertView中的组件不需要再次findViewById(),每个重用组件只需要findViewById()一次即可。而像上面那种,对于每次调用getView()则必定需要进行一次findViewById()的调用!
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
ViewHolder viewHolder=null;
Log.i(TAG, "getView()" + position);
if (convertView == null) {
// 若为空,则动态加载一个View
convertView = inflater.inflate(R.layout.list_item, null);
//ViewHolder初体验
viewHolder=new ViewHolder();
//减少findViewById()的执行
/*不需要每次调用getView()方法就必定调用findViewById()*/
viewHolder.mNetworkImageView=(NetworkImageView) convertView.findViewById(R.id.item_image);
viewHolder.textview=(TextView) convertView.findViewById(R.id.item_text);
convertView.setTag(viewHolder);
} else {
/*viewHolder通过getTag()完成初始化*/
viewHolder = (ViewHolder)convertView.getTag();
}
String IMAGE_URL = paths[position];
Log.i("MainActivity", "加载图片-------->"+position+"------>"+IMAGE_URL);
/*对于视图组件的内容设置需要在if else 外面*/
viewHolder.mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader);
viewHolder.textview.append("------>" + position);
return convertView;
}
静态ViewHolder类
public static class ViewHolder{
public NetworkImageView mNetworkImageView;
public TextView textview;
}