• Android笔记——提升ListView的运行效率


       之所以说 ListView 这个控件很难用,就是因为它有很多的细节可以优化,其中运行效率就是很重要的一点。目前我们ListView 的运行效率是很低的,因为在 FruitAdapter getView()方法中每次都将布局重新加载了一遍,当 ListView 快速滚动的时候这就会成为性能的瓶颈。

           仔细观察,getView()方法中还有一个 convertView 参数,这个参数用于将之前加载好的布局进行缓存,以便之后可以进行重用。修改 FruitAdapter 中的代码,如下所示:

     1 public class FruitAdapter extends ArrayAdapter<Fruit> {
     2 
     3 ……
     4 
     5 @Override
     6 
     7 public View getView(int position, View convertView, ViewGroup parent) { Fruit fruit = getItem(position);
     8 
     9 View view;
    10 
    11 if (convertView == null) {
    12 
    13 view = LayoutInflater.from(getContext()).inflate(resourceId, null); } else {
    14 view = convertView;
    15 
    16 }
    17 
    18 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());
    19 
    20 return view;
    21 
    22 }
    23 
    24 }

       可以看到,现在我们在 getView()方法中进行了判断,如果 convertView 为空,则使用 LayoutInflater 去加载布局,如果不为空则直接对 convertView 进行重用。这样就大大提高了 ListView 的运行效率,在快速滚动的时候也可以表现出更好的性能。

           不过,目前我们的这份代码还是可以继续优化的,虽然现在已经不会再重复去加载布局,但是每次在getView()方法中还是会调用View findViewById()方法来获取一次控件的实例。我们可以借助一个 ViewHolder 来对这部分性能进行优化,修改 FruitAdapter 中的代码,如下所示:

     

     1 public class FruitAdapter extends ArrayAdapter<Fruit> {
     2 
     3 ……
     4 
     5 @Override
     6 
     7 public View getView(int position, View convertView, ViewGroup parent) { Fruit fruit = getItem(position);
     8 
     9 View view;
    10 
    11 ViewHolder viewHolder;
    12 
    13 if (convertView == null) {
    14 
    15 view = LayoutInflater.from(getContext()).inflate(resourceId, null); viewHolder = new ViewHolder();
    16 
    17 viewHolder.fruitImage = (ImageView) view.findViewById (R.id.fruit_image);
    18 
    19 viewHolder.fruitName = (TextView) view.findViewById (R.id.fruit_name);
    20 
    21 view.setTag(viewHolder); // 将ViewHolder存储在View中
    22 
    23 } else {
    24 
    25 view = convertView;
    26 
    27 viewHolder = (ViewHolder) view.getTag(); // 重新获取ViewHolder
    28 
    29 }
    30 
    31 viewHolder.fruitImage.setImageResource(fruit.getImageId());
    32 
    33 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

  • 相关阅读:
    轻松理解https,So easy!
    都 9102 年了,一起来攻克 Linux 吧!
    8种常见SQL错误用法,你中招了吗?
    如何写出让同事无法维护的代码?
    Spring Boot 2.1.6 发布了!
    推荐一款 MyBatis 开发神器,为简化而生!
    vs2015制作一个超级简单的MVC项目
    解析ASP.NET WebForm和Mvc开发的区别
    asp.net 的 web form 过时了吗
    Asp.net的WebForm的落后技术
  • 原文地址:https://www.cnblogs.com/wugu-ren/p/6106422.html
Copyright © 2020-2023  润新知