码迷,mamicode.com
首页 > 其他好文 > 详细

欢迎使用CSDN-markdown编辑器

时间:2015-06-06 00:30:09      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:android   listview   优化   

重用 ListView Item

ListView创建时其会创建屏幕可容纳数量的 Item,ListView 滚动时,刚消失的 item 会被保存到回收池中,新出现的 item 从回收池中获取避免重复创建,这个回收池由 ListView 维护。从回收池取出 item 会传递给 Adapter 的 getView() 方法的第二个参数,如果回收池中没有内容就传递一个 null。所以在 getView() 方法中如果第二个参数不为 null,就不要创建新的 ListView Item了,这可以极大的提高 ListView 性能。

public void getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    if (view == null) {
         // 创建新的 ListView item
         view = LayoutInflator.from(mContext).inflate(...);
     }

    /* 更新 ListView Item */
    TextView textView = (TextView)view.findViewById(R.id.textview);
    textView.setText("new data");

    return view;
}

getView() 中避免每次调用 findViewById()

使用上面重用 ListView Item 的方法已经可以大幅提高 ListView 的效率了,但还存在一些可以改进的地方,上面每次更新 ListView Item 数据时,都要通过 View 的 findViewById() 方法定位每个子控件, findViewById() 会沿着ListView Item 的控件布局结构遍历每个控件直到找到指定 id 的控件,这是比较耗时的,尤其是布局比较复杂时。优化方法很简单,在每次创建新的 ListView Item 时保存通过 findViewById() 找到的每个子控件的引用。这些控件引用可以保存在一个单独的对象中,一般命名为 ViewHolder,然后将 ViewHolder 对象存储在 ListView item 中(通过 View 的 setTag() 方法,该方法可以在 View 中存储额外数据),下次可以直接从 ListView item 中取得。

public void getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
    if (view == null) {
         // 创建新的 ListView item
         view = LayoutInflator.from(mContext).inflate(...);
         // 保存控件引用在 ViewHolder 对象中
         ViewHolder holder = new ViewHolder();
         holder.textView = (TextView)view.findViewById(R.id.textview);
         // 将 ViewHolder 对象保存在 ListView Item 中
         view.setTag(holder);
     }

    /* 更新 ListView Item */
    ViewHolder holder = (ViewHolder)view.getTag();
    holder.textView.setText("new data");

    return view;
}

private static class ViewHolder {
    public TextView textView;
}

解决 ListView 重复调用 getView() 的问题

由于 ListView 高度或宽度不固定(布局参数中的宽或高指定为 wrap_content),导致 ListView 重绘时需要重新计算 ListView Item 的大小,从而导致 getView() 方法重复调用。这对 ListView 的性能有显著的影响,解决办法就是指定 ListView 布局参数中的高和宽为固定大小或 match_parent

避免更新相同数据

当 ListView Item 中包含图片控件时, 在 getView() 中更新数据一般是根据图片的 URI 取得 Bitmap 然后设置图片,如果 ImageView 显示的图片地址和要更新的图片地址相同,就完全没有必要做更新操作。可以采用和 ViewHolder 相同的方式,将图片的 URI 地址保存在 ImageView 的 tag 中,每次更新 ImageView 时先判断图片地址是否发生变化,只有发生变化时采取获取新的 Bitmap 更新。

String newImgUrl = ...;
String imgUrl = (String)imageView.getTag();
if (imageUrl == null || !imageUrl.equal(newImgUrl)) {
    // 请求 newImgUrl 对应的图片
    Bitmap bitmap = ...;
    imageView.setImageBitmap(bitmap);
    imageView.setTag(newImgUrl);
}

限制 ListView 的滚动速度

ListView 默认的滚动速度是比较快的,如果 ListView 滚动速度慢一点,那么每个 ListView Item 就有更多的加载时间,这也可以使 ListView 看上去更加流畅。下面代码将 ListView 的滚动速度减慢为原来的 1/10:

listview.setFriction(ViewConfiguration.getScrollFriction() * 10);

欢迎使用CSDN-markdown编辑器

标签:android   listview   优化   

原文地址:http://blog.csdn.net/xiaohui_hubei/article/details/46382911

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!