RecyclerView与ListView的区别

缓存

RecyclerView的缓存:( tryGetViewHolderForPositionByDeadline这个方法)

  • mAttachedScrap第一级缓存,用于快速重现屏幕上的ViewHolder。主要是用来存放ViewHolder兑现的ArrayList,这一级缓存没有容量限制,这里的数据不做修改,不会重走Adapter的绑定方法(ViewHolder视图还在屏幕中)

  • mChangedScrap这个变量和上面的mAttachedScrap一样,唯一不同的是这里存放的是发生了变化的Viewholder,如果使用这里发生变化的ViewHolder需要重走Adapter的绑定数据方法(ViewHolder视图还在屏幕中)

  • mCacheViews这里同样是一个存放ViewHolder的ArrayList,这里存放的是dettach掉的视图,它里面存放的已经remove掉的视图(滚出屏幕),已经和RecyclerView分离关系的视图,但它里面的ViewHolder依然保存着之前的信息数据,这一级缓存默认是缓存两个(有容量限制),
    可以通过setItemViewCacheSize(5)方法修改容量

  • mViewCacheExtension 是一个抽象静态类,用于充当附加的缓存池,官方没有实现,默认是null

  • RecyclerViewPool Viewholder缓存池,这里保存的ViewHolder不仅仅是removed掉的视图,而且是恢复了出厂设置的视图,任何白给你定过的痕迹都没有了,想用这里的缓存的ViewHolder那是铁定要重新走A倒塌而的绑定方法了,而且由于RecyclerView支持多布局,所里这里的缓存是按照itemType来分开存储的,每一个type默认的存储数量是5

  • 滑出屏幕的item首先存放在mCacheView中,如果mCacheViews中已满,也就是有两个ViewHolder视图,mCacheViews会根据FIFO的方式,将之前缓存的ViewHolder移动到RecyclerViewpool,如果RecyclerViewPool也存储到最大值,就会被遗弃

  • 注意:缓存到mCacheView中的ViewHolder并不会清理相关信息(比如poisition,state等),因此刚一出屏幕的ViewHolder,再次被移回屏幕时,只要从CacheView中查找并显示即可,不需要重新绑定,而被缓存到RecyclerViewPool中的ViewHolder会被清理状态和位置信息,因此从RecyclerViewPool查找到的ViewHolder,需要重新调用bindViewHolder绑定数据

ListView的缓存

  • mActiveViews 第一级缓存,这些View是布局过程开始时屏幕上的View,layout开始时这个数组被填充,layout结束,mActiveViews中的View移动到mScrapView,意义在于快速重现屏幕上课件的列表项ViewItem,而不需要重选createView和bindView
  • mScrapView 第二级缓存,mScrapView是多个List组成的数据,数组的长度为viewTypeCount,每个List缓存不同类型的Item布局的View,其意义在于缓存离开屏幕的ItemView,目的是让即将进入屏幕的itemView重用,当mAdapter被更换时,mScrapViewsze被清空

RecyclerView优化

  • 数据处理和视频加载分离

    • 耗时的数据处理逻辑应该放在异步处理,这样Adaoter再notify改变数据的时候,ViewHolder可以操作数据与视图的绑定逻辑
  • 数据优化

    • 分页拉取数据时,对拉取下来的远端数据进行缓存,提升二次加载速度
    • 对于新增挥着删除的数据通过DiffUtil来进行局部刷新数据,而不是一味地刷新数据
  • 减少布局层级和过度绘制

    • 可以通过自定义View或者更合理的设置布局来减少层级,移除不必要的背景减少过度绘制
  • 减少xml文件inflate时间

    • 这里的xml文件不急包括layout的xml,还包括当然玩乐的xml,xml文件inflate出itemView时通过耗时的IO操作,尤其当item的复用几率很低的情况下,随着Type的增多,这种inflate带来的损耗是相当大的,此时可以用代码去生成布局
  • 减少对象的创建

    • 一个稍微复杂的Item会包含大量的View,而大量的View的创建也会消耗大量的时间,所以要尽可能的简化ItemView
    • 设计itenType时,对多ViewType能够共用的部分尽量设计成自定义View,煎炒View的构造和嵌套
  • 使用RecyclerView的prefetch功能(预取功能), 提前处理完数据,然后将得到的itemholder缓存起来,等到真正要使用的时候直接从缓存取出来即可,默认是开启的

  • 如果item高度是固定的话,可以使用RecyclerView.setHasFixedSize(true)来避免requestLayout浪费资源

  • 滑动过程中停止数据和图片的加载

  • 不弱不需要动画,把默认动画关闭来提升效率,动画再Android系统中是一个很大的开销

  • 通过RecyclerView.setItemViewCacheSize(size)来加大RecyclerView的缓存,用控件换时间来提高滚动的流畅性

  • 如果多个RecyclerView的Adapter是一样的,比如嵌套的RecyclerView存在一样的Adapter,可以通过设置RecyclerView.setRecyclerViewPool
    方法来共用一个RecyclerViewPool

  • 在onBindView的时候,只做绑定工作,不要创建对象

  • 监听recyclerView滑动,实现列表滑动时停止加载图片,停止时再加载,glide有两个方法:Glide.with(mContext).resumeRequests()
    Glide.with(mContext).pauseRequests(),如果是Picasso,则需要对相应的imageView添加tag,Picasso.get().resumeTag(tag),
    Picasso.get().pauseTag(tag);

你可能感兴趣的:(RecyclerView与ListView的区别)