之所以说 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. wpf 加载项目图片的几种写法

    new System.Windows.Media.Imaging.BitmapImage( new Uri("pack://application:,,,/TeacherAssistant. ...

  2. 在Javascript中onclick()方法应用

    <html> < head> < script type="text/javascript"> function onclick1(){ ale ...

  3. GDB调试汇编堆栈

    GDB调试汇编堆栈 分析过程 C语言源代码 int g(int x) { return x+6; } int f(int x) { return g(x+1); } int main(void) { ...

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

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

  5. Windows下ActiveMQ下载、安装部署

    1.下载:http://activemq.apache.org/download.html 最新Windows版本   2.安装 (1) 首先配置JAVA环境变量 JAVA_HOME=D:\Progr ...

  6. gulp-less解决遇到错误停止执行task

    来龙去脉 在用less+gulp开发时,有时候代码还没写完整,不小心保存了一下,然后gulp就开始执行gulp-less的task. 但是代码是有问题的,这时候会输出一个Potentially unh ...

  7. xxxxxxxx

    class IndexHandler(BaseRequestHandler): def get(self, page=1): print('iiiiiiiiiiiiiiiii') current_ti ...

  8. php获取excel所有的批注

    phpexcel下载:https://github.com/PHPOffice/PHPExcel <?php /** *获取excel所有的批注 * * 存在编码问题,xls和xlsx的批注编码 ...

  9. 2016huasacm暑假集训训练五 E - What Is Your Grade?

    题目链接:http://acm.hust.edu.cn/vjudge/contest/126708#problem/E 题意:给做出的题目个数,5个的100分,4个的前n/2的同学95,后n/2的90 ...

  10. mysql添加一个用户

    对于添加mysql的远程访问用户,一定要记得刷新刷新系统权限表不然你怎么弄都是不成功的. insert into mysql.user(Host,User,Password) values(" ...