在Android开发中,ListView的使用频率及其高,可以说99%的应用中你都可以看到他的身影。
在日常的开发工作中,我们一般会通过以下方法来优化ListView的效率:
1.复用getView方法中的convertView
一个ListView可能有很多Item,但是限于手机屏幕非常有限,所以只能显示很少的一部分Item,比如能显示10个,那么Android会在ListView中保存多余10个的Item,
溢出屏幕的Item会被回收到一个池子中,以备后用,那么就不用从新new出View对象,这样大大提高了ListView的加载速度。
2.使用ViewHolder模式
在最新的Android5.0中,这种模式已经被RecylerView使用,可见这种模式确实非常有效。
我们来看下ViewHolder的定义:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public static class ViewHolder{ 2 public TextView texView; 3 public ImageView imageView; 4 public LinearLayout linearLayout; 5 ........ 6 }
ViewHolder中保存的都是View对象,这样避免了当我们可以复用converView的时候,需要使用convertView.findViewById来查找View,
这种查找的过程随着布局层次的加深会有性能上的消耗。
3.使用异步
在ListView中我们要避免耗时操作,最常见的就是加载图片。这个可以用单独的篇幅来讨论,这里就不多写了。
4.优化converView的布局
ListView中有很多Item,每个Item的绘制、测量、布局都需要消耗时间,这样会导致View的加载效率很低,所以应该避免嵌套层次过多。
5.如果界面需要非常频繁的更新,可以控制更新的频率和更新特定的Item
我们知道,如果ListView使用Adapter中数据有变化,我们会调用Adapter.notifyDataSetChanged方法来刷新界面,但是这个方法会刷新所有Item,但有的时候这不是我们想要的。
比如,我们在做一个下载器,ListView的每个Item都可能收到进度的更新,如果不对更新频率加以控制,那么界面一定会卡死,产生ANR。所以我们必须在通知进度更新的地方,加上频率控制,比如每隔3秒通知UI刷新一次。
另外,并不是所有的Item都需要刷新,我们没必要去调用Adapter.notifyDataSetChanged方法。在需要刷新的方法中,我们可用通过ListView.getChildAt(int index)方法,获取出当前ListView显示的Item,判断这些Item
哪些是需要更新的,然后设置UI的状态,这样ListView的效率能更进一步的得到提升。
6.在滑动的时候避免加载图片
这个方法可能不会提高ListView的加载速度,但是会提高用户体验。具体做法是:在ListView滑动的时候,不要发送加载图片的请求,保持你的线程池中的请求队列不会有过多的请求,尤其是用户快速滑动过的Item中要加载的图片,
这样可以保证ListView停止滑动的时候,下载队列中的请求尽可能多的是当前显示给用户的Item中的图片请求。