您的位置:首页 > 移动开发 > Android开发

用ViewHolder优化显示性能

2017-09-05 21:50 141 查看
使用adapter对ListView,GridView等进行适配时,要重写它的getView()方法。

下面是一个简单的示例,从本博客的上一篇文章Android launcher应用的简单实现粘贴过来:

@Override
public View getView(int i, View view, ViewGroup viewGroup) {

//这里没有用ViewHolder
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
View appView = inflater.inflate(R.layout.icon_layout, null);

ImageView iv = (ImageView) appView.findViewById(R.id.app_icon);
//设置图标适应方式和大小
iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
iv.setLayoutParams(new LinearLayout.LayoutParams(70, 70));
TextView tv = (TextView) appView.findViewById(R.id.app_name);

ResolveInfo info = apps.get(i);

//显示app图标
iv.setImageDrawable(info.activityInfo.loadIcon(getPackageManager()));
//显示app名
String appName = info.loadLabel(getPackageManager()).toString();
tv.setText(appName);
return appView;
}
}


要显示多少数据,getView就会执行多少次。而按这种实现,每次都会创建一个view,是效率很低的做法。

下面稍稍改下:

@Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (null == view) {
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
view = inflater.inflate(R.layout.icon_layout, null);
}
ImageView iv = (ImageView) view.findViewById(R.id.app_icon);
//设置图标适应方式和大小
iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
iv.setLayoutParams(new LinearLayout.LayoutParams(70, 70));
TextView tv = (TextView) view.findViewById(R.id.app_name);

ResolveInfo info = apps.get(i);
//显示app图标
iv.setImageDrawable(info.activityInfo.loadIcon(getPackageManager()));
//显示app名
String appName = info.loadLabel(getPackageManager()).toString();
tv.setText(appName);

return view;
}


上面进行修改之后,不会每次都重新创建view了,而是view为null时才创建,效率有所提升。但这并不是最好的优化。下面看看用ViewHolder进行优化:

先在adapter的外面定义一个类ViewHolder:

static class ViewHolder{
ImageView img;
TextView tv;
}


然后对adapter的getView()方法进行如下修改:

@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (null == view) {
LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
view = inflater.inflate(R.layout.icon_layout, null);

holder = new ViewHolder();
holder.img = (ImageView) view.findViewById(R.id.app_icon);
holder.tv = (TextView) view.findViewById(R.id.app_name);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}

//设置图标适应方式和大小
holder.img.setScaleType(ImageView.ScaleType.FIT_CENTER);
holder.img.setLayoutParams(new LinearLayout.LayoutParams(70, 70));

ResolveInfo info = apps.get(i);
//显示app图标
holder.img.setImageDrawable(info.activityInfo.loadIcon(getPackageManager()));
//显示app名
String appName = info.loadLabel(getPackageManager()).toString();
holder.tv.setText(appName);

return view;
}


这样修改之后,避免每次调用getView()的时候都调用findViewById(),因此更进一步提升了性能,因为findViewById()也是耗费性能的操作。

另外需要说明下,ViewHolder这个名字换成别的自定义名也行,但是ViewHolder这个名字是官方推荐的,而且大家都这样写,所以最好约定俗成地保持这种习惯。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息