说到ListView优化,不得不谈谈五月份开发的校园社交App。耗时最长的就在ListView的性能优化上。
最开始遇到的问题是,大量加载本地图片,UI渲染跟不上,原因是UI控件的实例太多,不能及时的回收。通过构建adapter的内部类,存储控件的实例,实现UI控件的复用,解决了该问题。但是,尼玛,同时又发现了新的问题。当滑动过快时,已经在界面外的图片还存留在界面中。参考某大神的做法(忘了是哪位),利用ImageView的Tag,给控件做标识。加载到该图片时,判断Tag是否相同,相同即加载图片。
解决问题一1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHold hold = new ViewHold();
if (convertView == null) { // converView 不存在,则实例化
convertView = inflater.inflate(R.layout.item, null);
hold.iv = (ImageView) convertView.findViewById(R.id.iv);
convertView.setTag(hold);
} else { // converView 已存在,这使用Tag,实现复用
hold = (ViewHold) convertView.getTag();
}
return convertView;
}
/**
* 内部类,存储控件实例
*/
class ViewHold {
public ImageView iv;
}
解决问题二
一般情况下是加载网络图片才会出现该问题!
截取,校园社交App部分解决该问题的代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
avatarUrl = user.getAvatar().getFileUrl(context);//Activity传过来的头像地址
if (avatarUrl != null) {
holder.avater.setTag(avatarUrl);//为承载该图片的ImageView建立标识
Bitmap bitmapavater = asyncBitmapLoader.loadBitmap(//异步下载图片
holder.avater, avatarUrl, listview.isScrolling,
new ImageCallBack() {
@Override
public void imageLoad(ImageView imageView,
Bitmap bitmap) {
imageView.setImageBitmap(bitmap);
}
});
if (bitmapavater == null) {
holder.avater
.setImageResource(R.drawable.user_icon_default_main);
} else if (holder.avater.getTag().equals(avatarUrl)) {//判断与之前的Tag是否相同,相同即加载
holder.avater.setImageBitmap(bitmapavater);
}
}
当然了,ListView的优化远远不止这些,如ListView快速滑动的同时加载网络图片,会出现卡顿,闪屏等等!日后有时间再继续写 ListView优化 二