1.convertView优化快速滚动效率
getView()中有一个名为convertView的参数,其用于将之前加载好的布局进行缓存,以便重用。上代码,
@Override
public View getView(int position, View convertView, ViewGroup parent){
Fruit fruit = getItem(position); //获取当前项的Fruit实例
/*原方法,View view = LayoutInflater.from(getContext()).inflate(resourceId, null);*/
/*使用convertView */
View view;
if (convertView == null){
view = LayoutInflater.from(getContext().inflate(resourceId, null));
}
else{
view = convertView;
}
ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
TextView fruitName = (TextView) view.findViewById(R.id.fruit_name);
fruitImage.setImageResource(fruit.getImageId());
fruitName.setText(fruit.getName());
return view;
}
如代码注释,注释内的为原方法,每次getView都需要将布局重新加载一遍,当ListView快速滚动时会有性能障碍。
使用convertView方法后,首先判断convertView是否为空,若为空,使用LayoutInflater来加载布局;若不为空,直接对convertView进行重用。
LOL
2.ViewHolder对控件实例进行缓存
还是如上的代码中,我们发现,每次在getView()方法中都会调用view中的findViewById来获取一次控件的实例。
该ViewHolder闪亮登场了,直接上代码,
@Override
public View getView(int position, View convertView, ViewGroup parent){
Fruit fruit = getItem(position); //获取当前项的Fruit实例
/*原方法,View view = LayoutInflater.from(getContext()).inflate(resourceId, null); */
/*原方法,
ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
TextView fruitName = (TextView) view.findViewById(R.id.fruit_name);
fruitImage.setImageResource(fruit.getImageId());
fruitName.setText(fruit.getName());*/
viewHolder.fruitImage.setImageResource(fruit.getImageId());
viewHolder.fruitName.setText(fruit.getName());
//使用convertView
View view;
ViewHolder viewHolder;
if (convertView == null){
view = LayoutInflater.from(getContext()).inflate(resourceId, null);
//将ViewHolder存储在View中
viewHolder = new viewHolder();
viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name);
view.setTag(viewHolder); /*将ViewHolder存储在View中*/
}
else{
view = convertView;
viewHolder = (ViewHolder) view.getTag(); //重新获取ViewHolder
}
return view;
}
class ViewHolder{
ImageView fruitImage;
TextView fruitName;
}
注意看新增的部分。
新建了一个内部类ViewHolder,用于对控件的实例进行缓存。
若convertView为空,创建ViewHolder对象,并将所有控件的实例都存在ViewHolder中,接着调用view的setTag()方法,将ViewHolder对象存放在view中;
若convertView不为空,调用view的getTag()方法,将ViewHolder重新取出。
因此,所有的控件实例都缓存在了ViewHolder中,不必如原方法般每次都通过findViewById来依次获取控件实例,从而优化了性能。么么哒。
LOL
没有评论:
发表评论