Android ListView中复杂数据流的高效渲染(一)

更新:目前已经写了demo,欢迎讨论:Android复杂数据流的“高效”渲染javascript

咱们知道Android中的ListView之因此能够实现item的无限加载,是由于对每一个item的View 进行了缓存复用。ListView的高效性能使得其在App开发中使用很是频繁,本文主要分析在复杂数据展现时如何更加高效的使用ListView,如微博、facebook、twitter等的feed流须要展现很是多的数据类型:新闻、图片、网页连接、视频,这种状况下ListView进行须要缓存各类类型的View,App的内存占用急剧升高……java

ListView复用原理

1. 简单列表复用

首先简单介绍一下ListView的复用原理,咱们知道使用ListView时通常须要结合Adapter使用,继承BaseAdapter时,通常须要实现四个方法:缓存

@Override
    public int getCount() {
        return 0;
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return null;
    }复制代码

其中getView是渲染每一个Item时进行回调生成View的,方法参数convertView就是ListView传回能够复用的View,当其不为null时,无需从新建立View,能够直接使用convertView,进行数据渲染便可。其原理是当第一次调用时ListView直接将生成的View缓存到一个ArrayList 中,当须要时直接从ArrayList中取出便可: ide

Paste_Image.png

2. 复杂列表复用

当列表中有多种类型的view时,咱们须要实现BaseAdapter中的:性能

@Override
    //返回view类型数量
    public int getViewTypeCount() {
        return super.getViewTypeCount();
    }

    @Override
    //返回每一个Item的类型
    public int getItemViewType(int position) {
        return super.getItemViewType(position);
    }复制代码

这种状况下ListView实际为每种类型的Item设置了一个ArrayList进行缓存:优化

Paste_Image.png

复杂信息流

此处以微博为例:ui

  • 转发带视频类型
    Paste_Image.png
  • 普通文字+卡片类型

  • 转发图文类型


此外还有原创图文类型,原创视频,原创卡片,系统通知,转发视频,转发图文,……,微博有多达二十种左右的item类型,每种类型中的View可能包括头部图片、文字描述、正文内容、正文图片、正文视频、分享操做栏等内容,这些都缓存到内存中,再加上二十多种类型,想一想内存的感觉……

优化

咱们能够看到不少类型中都有相同能够复用的部分,如头部、分享操做栏等不少item中都是同样,是否可单独拿出来呢,咱们进行简单的拆分:spa

Paste_Image.png

一个Item咱们把它拆为来五个部分, 首先头部、评论操做栏等能够在不少不一样类型的数据Item中进行复用,文字、图片等的View也能够单独进行复用,并且最重要的是:缓存ArrayList中保存的View数量将会减小,内存消耗减了很多

具体实现中的坑

看到这里,是否是不少同窗以为打开了新世界的大门,急着进行代码的优化?具体的代码不方便贴出来,这里说一下具体实现过程当中碰到的坑:3d

  • item click事件
    因为优化的需求,把逻辑上的一个Item拆分为了多个item,所以每一个item上都要设置ItemClick事件。具体实现时能够写一个基类,在基类中对item click进行处理。
  • cover 按压效果
    在item 点击时,通常须要有按压效果,此时逻辑上的item已经进行了拆分,须要策略实现逻辑上item的总体按压,而不是只有某个拆分后的item被按压。
  • divider
    咱们知道listview的item之间是有divider的,此时须要设置divider为null,咱们经过添加item的方式来实现divider效果。

效果

等填完拆分后的坑,运行程序,观察先后的效果,内存占用能够减小10~20m,滑动流畅度也提升很多,在低端手机上的效果尤为明显,掉帧明显减小。很是建议有须要的同窗尝试。code

Other

欢迎关注公众号wutongke,天天推送移动开发前沿技术文章:

wutongke
相关文章
相关标签/搜索