菜鸟刚入行时,写ListView时会写成下面这样,在滑动时会发现很卡,特别是数据多的时候。这时候就需要优化了。怎么优化?接着看。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//省略获取数据操作
//视图绑定操作
convertView=View.inflate(MainActivity.this, R.layout.item, null);
TextView tvTitle = convertView.findViewById(R.id.tv_title);
//省略数据绑定操作
return convertView;
}
有哪些需要优化的?
- 视图膨胀操作(inflate),耗时
convertView=View.inflate(MainActivity.this, R.layout.item, null);
- 控件查找操作(findViewById),耗时
TextView tvTitle = convertView.findViewById(R.id.tv_title);
怎么看出来的?
- 亲手体验
- 使用Eclipse的DDMS视图查看Heap内存使用和回收情况
- 使用sdk/tools/hierarchyviewer.bat查看视图树
怎么优化?
1. 使用视图回收器,减少inflate操作,降低视图频繁创建和回收对性能的影响
视图回收器不是别的,就是covertView。当原本可见的视图因滑动操作变得不可见时,系统会自动回收,转化成convertView供复用。使用了convertView后的代码如下:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//省略获取数据操作
//视图绑定操作
if(convertView==null){
convertView=View.inflate(MainActivity.this, R.layout.item, null);
}
TextView tvTitle = convertView.findViewById(R.id.tv_title);
//省略数据绑定操作
return convertView;
}
2. 使用视图持有者,减少findViewById操作(对视图树节点的查找),以内存空间换取时间,提高ListView加载速度
所谓的ViewHolder其实就是一个JavaBean对象,里面存放着本来需要findViewById的控件(一个View绑定一个ViewHolder),这样做回占用一定的内存,但是没有了视图查找操作,视图的加载变快了,当数据很多或者频繁滑动时性能提升很明显。使用了ViewHolder后的代码如下:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//省略获取数据操作
//视图绑定操作
ViewHolder holder=null;
if(convertView==null){
holder = new ViewHolder();
convertView=View.inflate(MainActivity.this, R.layout.item, null);
holder.tvTitle = convertView.findViewById(R.id.tv_title);
//打标签,意思是把convertView装进holder里,让它持有
convertVIew.setTag(holder);
}
//获取标签,意思是把holder拿出来
holder = (ViewHolder)convertView.getTag();
//从holder中拿出view
TextView tvTitle = holder.tvTitle;
//省略数据绑定操作
//VieHolder
class ViewHolder {
public TextView tvTitle;
}
return convertView;
}