之所以说 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 {
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;

我们新增了一个内部类 ViewHolder,用于对控件的实例进行缓存。当 convertView 为空的时候,创建一个 ViewHolder 对象,并将控件的实例都存放在 ViewHolder 里,然后调用 View的 setTag()方法,将 ViewHolder 对象存储在 View 中。当 convertView 不为空的时候则调用 View 的 getTag()方法,把 ViewHolder 重新取出。这样所有控件的实例都缓存在了 ViewHolder里,就没有必要每次都通过 findViewById()方法来获取控件实例了。

通过这两步的优化之后,我们 ListView 的运行效率就已经非常不错了。

参考:《第一行代码Android》

资源:http://download.csdn.net/detail/u011457627/8697337

Android笔记——提升ListView的运行效率的更多相关文章

  1. android:提升 ListView 的运行效率

    之所以说 ListView 这个控件很难用,就是因为它有很多的细节可以优化,其中运行效率 就是很重要的一点.目前我们 ListView 的运行效率是很低的,因为在 FruitAdapter 的 get ...

  2. android笔记:ListView及ArrayAdapter

    ListView用于展示大量数据,而数据无法直接传递给ListView,需要借助适配器adapter来完成. ArrayAdapter是最常用的adapter,可以通过泛型来指定要适配的数据类型.常见 ...

  3. Android笔记:ListView

    listview属性 android:divider属性,可以指定ListView 分隔线的颜色,#0000 表示将分隔线设为透明色. listview效率的问题 adapter的三个参数int po ...

  4. 初识ListView - 定制ListView - 提升ListView运行效率

    ListView绝对可以称得上是 Android 中最常用的控件之一,几乎所有的应用程序都会用到它.由于手机屏幕空间都比较有限,能够一次性在屏幕上显示的内容并不多,当我们的程序中有大量的数据需要展示的 ...

  5. Android Studio 通过 ListView 学习 ArrayAdapte

    ListView •前言 ListView 绝对可以称得上是 Android 中最常用的控件之一,几乎所有的应用程序都会用到它. 由于手机屏幕空间有限,能够一次性在屏幕上显示的内容并不多,当我们的程序 ...

  6. android学习笔记12——ListView、ListActivity

    ListView.ListActivity ==> ListView以垂直列表的形式显示所有列表项. 创建ListView的方式: 1.直接使用ListView创建 2.Activity继承Li ...

  7. Android笔记: ListView基本用法-ArrayAdapter

    ListView实现过程: 新建适配器->添加数据源到适配器->视图加载适配器 数据适配器: 把复杂的数据(数组.链表.数据库.集合等)填充在制定的试图界面上. 两种常用数据适配器 Arr ...

  8. Android笔记(十)ListView

    ListView是Android中最经常使用的控件之中的一个,也是最难用的控件. ListView的作用是展示大量的数据,只是ListView并非直接和数据打交道.而是通过适配器作为中间桥梁. 1.首 ...

  9. Android笔记(二十五) ListView的缓存机制与BaseAdapter

    之前接触了ListView和Adapter,Adapter将数据源和View连接起来,实际应用中,我们要显示的数据往往有很多,而屏幕只有那么大,系统只能屏幕所能显示的内容,当我们滑动屏幕,会将旧的内容 ...

随机推荐

  1. 解决autolt上传图片报错cannot open system clipboard

    今天调试代码,发现本地可以上传图片,但是集成环境无法上传报错cannot open system clipboard: 百度查了下,我的系统没有剪切板程序,才报错. 验证方法如下: win+r,输入c ...

  2. img及父元素(容器)实现类似css3中的background-size:contain / background-size:cover

    img及父元素(容器)实现类似css3中的background-size:contain / background-size:cover <!DOCTYPE html> <html ...

  3. oracle中row_number和rownum的区别和联系(翻译)

    http://www.tuicool.com/articles/bI3IBv 附问题:有以下一个SQL语句: SELECT * FROM ( SELECT t.*, row_number() OVER ...

  4. 数据库SQL优化大总结之 百万级数据库优化方案

    1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  5. 根据url下载图片

    如题:在我要动手写的时候才发现不搜索根本就是写不出来,究其原因还是因为基础不扎实,由于用的少已经没有能力写出了 首先需要获取url数据流,然后写进文件里即可,仅仅两步可惜我写不出来啊跟着搜来的内容写一 ...

  6. 案例1.用Ajax实现用户名的校验

    用Ajax实现用户名的校验 java的验证类 public class UserDao { public boolean checkUserName(String name) { //这里的name是 ...

  7. 一个简便的方法,获取某个页面元素的Xpath值

    今天了解到一个比较方便获取页面元素Xpath的方法,以下是获取步骤. 1:使用chrome浏览器打开百度:http://www.baidu.com 2:点击邮件,检查. 3:定位到某个页面的元素:点击 ...

  8. Hibernate中Criteria的完整用法

    1,CriteriaHibernate 设计了 CriteriaSpecification 作为 Criteria 的父接口,下面提供了 Criteria和DetachedCriteria .2,De ...

  9. IntelliJ IDEA - 热部署插件JRebel 安装使用教程

    IntelliJ IDEA - JRebel 安装使用教程 JRebel 能做什么? JRebel 是一款热部署插件.当你的 Java-web 项目在 tomcat 中 run/debug 的时候 , ...

  10. 异步调用window.open时被浏览器阻止新窗口解决方案

    var wyWindow = window.open('_blank');$http.post($rootScope.baseUrl + '/Interface0231A.ashx', { userF ...