Android中优化listview的一种方案

该方法是在<第一行代码>的133-134页发现了,摘抄上来做笔记.

该方法是对adapter的getView()部分进行优化,在.View getview(int position, View convertview, ViewGroup parent )的第二个参数convertview,找到如下参考资料:链接http://blog.youkuaiyun.com/kongzhichen/article/details/10721197


可以简单理解为如果该View是第一次创建则为null,后面如果移出屏幕外面再回来的时候,后返回的就不是null,而是上一次创建的那个View对象.View中有一个setTag()方法,我们可以利用这个方法来存一些数据.也就是把当前view中所有的子View放到SetTag()中,待下次需要用到的时候就直接取出来进行操作就可以了,而不必再次从布局文件中获取.


下面贴上电子版的截图








以下是文本内容:


3.5.3 提升 ListView 的运行效率
之所以说 ListView这个控件很难用,就是因为它有很多的细节可以优化,其中运行效率
就是很重要的一点。目前我们ListView的运行效率是很低的,因为在 FruitAdapter的getView()
方法中每次都将布局重新加载了一遍,当 ListView快速滚动的时候这就会成为性能的瓶颈。
仔细观察,getView()方法中还有一个 convertView 参数,这个参数用于将之前加载好的
布局进行缓存,以便之后可以进行重用。修改 FruitAdapter中的代码,如下所示:
public class FruitAdapter extends ArrayAdapter<Fruit> {
……
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Fruit fruit = getItem(position);
View view;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resourceId, null);
} else {
第 2 章 先从看得到的入手,探究活动
135
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()方法中进行了判断,如果 convertView 为空,则使用
LayoutInflater 去加载布局,如果不为空则直接对 convertView进行重用。这样就大大提高了
ListView的运行效率,在快速滚动的时候也可以表现出更好的性能。
不过,目前我们的这份代码还是可以继续优化的,虽然现在已经不会再重复去加载布局,
但是每次在getView()方法中还是会调用View的findViewById()方法来获取一次控件的实例。
我们可以借助一个 ViewHolder来对这部分性能进行优化,修改 FruitAdapter 中的代码,如下
所示:
public class FruitAdapter extends ArrayAdapter<Fruit> {
……
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Fruit fruit = getItem(position);
View view;
ViewHolder viewHolder;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resourceId, null);
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
}
viewHolder.fruitImage.setImageResource(fruit.getImageId());
viewHolder.fruitName.setText(fruit.getName());
return view;
第一行代码 —— Android
136
}
class ViewHolder {
ImageView fruitImage;
TextView fruitName;
}
}
我们新增了一个内部类 ViewHolder,用于对控件的实例进行缓存。当 convertView为空
的时候,创建一个 ViewHolder对象,并将控件的实例都存放在 ViewHolder 里,然后调用 View
的 setTag()方法,将 ViewHolder 对象存储在 View 中。当 convertView 不为空的时候则调用
View的 getTag()方法,把 ViewHolder 重新取出。这样所有控件的实例都缓存在了 ViewHolder
里,就没有必要每次都通过 findViewById()方法来获取控件实例了。
通过这两步的优化之后,我们 ListView的运行效率就已经非常不错了。



public class FruitAdapter extends ArrayAdapter<Fruit> {
……
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Fruit fruit = getItem(position);
View view;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resourceId, null);
} else {
第 2 章 先从看得到的入手,探究活动
135
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()方法中进行了判断,如果 convertView 为空,则使用
LayoutInflater 去加载布局,如果不为空则直接对 convertView进行重用。这样就大大提高了
ListView的运行效率,在快速滚动的时候也可以表现出更好的性能。
不过,目前我们的这份代码还是可以继续优化的,虽然现在已经不会再重复去加载布局,
但是每次在getView()方法中还是会调用View的findViewById()方法来获取一次控件的实例。
我们可以借助一个 ViewHolder来对这部分性能进行优化,修改 FruitAdapter 中的代码,如下
所示:
public class FruitAdapter extends ArrayAdapter<Fruit> {
……
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Fruit fruit = getItem(position);
View view;
ViewHolder viewHolder;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resourceId, null);
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
}
viewHolder.fruitImage.setImageResource(fruit.getImageId());
viewHolder.fruitName.setText(fruit.getName());
return view;
第一行代码 —— Android
136
}
class ViewHolder {
ImageView fruitImage;
TextView fruitName;
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值