在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候,会占据大量内存,影响性能,这时候就需要按需填充并重新使用view来减少对象的创建。

ListView加载数据都是在public View getView(int position, View convertView, ViewGroup parent) {}方法中进行的(要自定义listview都需要重写listadapter:如BaseAdapter,SimpleAdapter,CursorAdapter的等的getvView方法),优化listview的加载速度就要让convertView匹配列表类型,并最大程度上的重新使用convertView。

getview的加载方法一般有以下三种种方式:

最慢的加载方式是每一次都重新定义一个View载入布局,再加载数据

public View getView(int position, View convertView, ViewGroup parent) {

 View item = mInflater.inflate(R.layout.list_item_icon_text, null);

 ((TextView) item.findViewById(R.id.text)).setText(DATA[position]);

 ((ImageView) item.findViewById(R.id.icon)).setImageBitmap(

 (position & 1) == 1 ? mIcon1 : mIcon2);

 return item;

}

正确的加载方式是当convertView不为空的时候直接重新使用convertView从而减少了很多不必要的View的创建,然后加载数据

public View getView(int position, View convertView, ViewGroup parent) {

 if (convertView == null) {

 convertView = mInflater.inflate(R.layout.item, parent, false);

 }

 ((TextView) convertView.findViewById(R.id.text)).setText(DATA[position]);

 ((ImageView) convertView.findViewById(R.id.icon)).setImageBitmap(

 (position & 1) == 1 ? mIcon1 : mIcon2);

 return convertView;

 }

最快的方式是定义一个ViewHolder,将convetView的tag设置为ViewHolder,不为空时重新使用即可

static class ViewHolder {

TextView text;

ImageView icon;

}

public View getView(int position, View convertView, ViewGroup parent) {

 ViewHolder holder;

 if (convertView == null) {

 convertView = mInflater.inflate(R.layout.list_item_icon_text,

 parent, false);

 holder = new ViewHolder();

 holder.text = (TextView) convertView.findViewById(R.id.text);

 holder.icon = (ImageView) convertView.findViewById(R.id.icon);

 convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}

holder.text.setText(DATA[position]);

holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);

return convertView;

}

三种方式加载效率对比如下图所示:

说明:上述三个例子代码摘自google 2010 I/O大会

当处理一些耗时的资源加载的时候需要做到以下几点,以使你的加载更快更平滑:

1.   适配器在界面主线程中进行修改

2.   可以在任何地方获取数据但应该在另外一个地方请求数据

3.   在主界面的线程中提交适配器的变化并调用notifyDataSetChanged()方法

  1. convertView的作用 ?

    1. 减少view对象的创建
  2. ViewHolder是什么 ?
    1. 就是一个普通的类,成员变量有根布局里面的孩子对象.
  3. ViewHolder的作用 ?
    1. 减少孩子对象的创建,减少findViewById的时候.
  4. ViewHolder里面需要持有什么对象?
    1. 持有根布局里面的孩子对象
  5. 做ViewHolder需要什么条件?
    1. 一个类持有根布局里面的孩子对象即可
    2. 其实只要能有根布局就有了对于的孩子.孩子无非就是调用根布局的findViewById初始化即可
  6. 一个ListView会创建几个convertView以及几个ViewHolder的思考
    1. 如果一个屏幕正好显示6个itemView那么会创建6+1个convertView和6+1个ViewHolder
  7. getView其实主要是做啥?
    1. 决定根布局
    2. 得到数据
    3. 填充数据

[转]ListView学习笔记(二)——ViewHolder的更多相关文章

  1. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  2. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  3. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  4. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

  5. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  6. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

  7. 《SQL必知必会》学习笔记二)

    <SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...

  8. NumPy学习笔记 二

    NumPy学习笔记 二 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.<数学分 ...

  9. Learning ROS for Robotics Programming Second Edition学习笔记(二) indigo tools

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  10. Redis学习笔记二 (BitMap算法分析与BitCount语法)

    Redis学习笔记二 一.BitMap是什么 就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身.我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省 ...

随机推荐

  1. 我认为比较有用的快捷键(Eclipse)

    http://hi.baidu.com/%D4%AD%CA%BC%C1%F7%C0%CB%D5%DF/blog/item/e497b94dd1b0b92daec3ab36.html 我认为比较有用的快 ...

  2. 修改Subversion用户登录密码

    找到svn建立的repository地址 %repository%/xxxx库/conf/   修改passwd文件即可

  3. 谈谈easyui datagrid 的数据加载(转)

    这篇文章只谈jQuery easyui datagrid 的数据加载,因为这也是大家谈论最多的内容.其实easyui datagrid加载数据只有两种方式:一种是ajax加载目标url返回的json数 ...

  4. 学习WCF笔记之二

    一.学习文章http://www.cnblogs.com/iamlilinfeng/archive/2012/09/25/2700049.html 二.步骤 学习WFC,按照大神的文章一步步学习,不过 ...

  5. python学习笔记011——闭包

    1 定义 定义:在计算机科学中,闭包是词法闭包的简称,是引用了自由变量的函数 简单地说:闭包就是能够读取其他函数内部变量的函数,闭包是将函数内部和函数外部连接起来的桥梁.——来源百度百科 2 描述 形 ...

  6. R.string获取的是数字或者R.integer数字不对的问题

    String msg = R.string.menu_title; 获取menu_title的String值,但发现这样写报错,原因R.string.menu_title是int类型的,可是通过以下方 ...

  7. Linux中断 - High level irq event handler

    一.前言 当外设触发一次中断后,一个大概的处理过程是: 1.具体CPU architecture相关的模块会进行现场保护,然后调用machine driver对应的中断处理handler 2.mach ...

  8. __align

    __align关键字指示编译器在n字节边界上对齐变量. __align是一个存储类修饰符.它不影响函数的类型. 语法 __align(n) 其中:  n是对齐边界. n可以具有值1.2.4或者8. _ ...

  9. tp查询范围

    一.查询范围 //说明username和password是对应模型下的  scopeUsername($query) 和scopePassword($query)方法 //关键字scope 在控制器如 ...

  10. Model实例化类属性与值使用反射拼接成SQL语句

    public string GetInsertSqlByModel(Object o) { StringBuilder sbStart = new StringBuilder(); StringBui ...