今天给大家分享一个很实用的ViewHolder中的写法。这个大家肯定写adapter的时候是基本都会写的,主要是用来缓存控件,优化加载的效率。
- 很多时候,我们都是自定义一个adapter,然后继承BaseAdapter,并重写相关方法。最后在这个adapter类里写一个ViewHolder内容类,用来缓存控件用。写法如下:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.item_gv_picture, null);
holder.iv_Picture = (ImageView) convertView
.findViewById(R.id.iv_Picture);
convertView.setTag(holder);
}
holder = (ViewHolder) convertView.getTag();
holder.iv_Picture.setImageBitmap(bitmapEntities.get(position).getBmp());
holder.iv_Picture.setScaleType(ScaleType.FIT_XY);
return convertView;
}
/*控件缓存类*/
class ViewHolder {
ImageView iv_Picture;
}
- 上面的代码我就不细说了,大家都了解这是一般的写法。但是你有没有想过,如果你有很多的adapter需要写,那么你就需要在每一个adapter中都写这么一个ViewHolder内部类。一个两个还行,可以一旦多了,那就会很无趣,而且降低开发效率。
- 但是ViewHolder这么写(提供一个静态的方法用来返回缓存好的控件,更好的是添加一个私有的构造方法,防止外被实例化。)如下所示:
package com.example.viewholderutils;
import android.util.SparseArray;
import android.view.View;
/**
* ViewHolder的工具类
*
* @author 国外某位技术爱好者
* @sharer 邹奇
*
*/
public class ViewHolder {
// 添加私有构造函数防止外部实例化
private ViewHolder() {
}
/**
* 用来缓存控件,优化加载
* @param view itemView的布局
* @param id itemView布局中需要缓存控件的id
* @return 缓存后的控件(textView、imageView...等控件)
*/
@SuppressWarnings("unchecked")
public static View get(View view, int id) {
// 获取itemView的ViewHolder对象,并将其转型为SparseArray<View>
SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
if (viewHolder == null) {
// 如果viewHolder为空,就新建一个
viewHolder = new SparseArray<View>();
// 给view设置tag标签
view.setTag(viewHolder);
}
// 根据控件的id获取itemView布局的控件
View childView = viewHolder.get(id);
if(childView == null){
// 如果还没有缓存该控件,那么就根据itemView找到该控件
childView = view.findViewById(id);
// 缓存该控件
viewHolder.put(id, childView);
}
// 返回缓存好的控件
return childView;
}
}
大家也许会问为什么要在这个类里面私有化构造方法。下面的链接可以很好的进行解答:http://blog.chinaunix.net/uid-20577907-id-161606.html
- 这个ViewHolder工具类有了,在adapter类中如下使用,那么你将会极大的提高开发的效率:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
// 布局泵获取itemView的布局
convertView = inflater.inflate(R.layout.listview_test, null);
}
// 使用Viewholder类的静态方法缓存控件,并返回缓存后的控件
TextView tv_test = (TextView) ViewHolder.get(convertView, R.id.tv_test);
// 设置内容
tv_test.setText(list.get(position));
return convertView;
}
- 大家发现没有,直接用上面的ViewHolder工具类可以直接获取缓存好的控件,很方便快捷。
最后,用上面的写法一样可以成功的显示列表数据,如下图:
- 经过我的测试,确实很好用。希望各位可以好好的利用到自己的项目中,将ViewHolder这个类加入自己的utils,这样可以减少很多重复代码。