美学原理RecyclerView与ListView 对比分析:缓存机制

一. 背景

PS:相关文化:
ListView与RecyclerView缓存机制原理大致相像,如下图所示:

美学原理 1

滑过程遭到,离屏的ItemView即被回收到缓存,入屏的ItemView则会优先由缓存中获取,只是ListView与RecyclerView的兑现细节来两样异.(这就是缓存使用的里一个场面,还有如刷新等)

二. 正文

2.1 缓存机制对比

  1. 层级不同:
    RecyclerView比ListView多简单级缓存,支持多单离ItemView缓存,支持开发者自定义缓存处理逻辑,支持所有RecyclerView共用以及一个RecyclerViewPool(缓存池)。

具体来说:
ListView(两级缓存):

美学原理 2

RecyclerView(四层缓存):

美学原理 3

ListView和RecyclerView缓存机制基本一致:

1).
mActiveViews和mAttachedScrap功能相似,意义在于快速重用屏幕及可见的列表项ItemView,而未欲重新createView和bindView;
2). mScrapView和mCachedViews +
mReyclerViewPool功能相似,意义在于缓存离开屏幕的ItemView,目的是被将上屏幕的ItemView重用.
3).
RecyclerView的优势在a.mCacheViews的运,可以成功屏幕外的列表项ItemView进入屏幕外不时也无须bindView快速重用;b.mRecyclerPool可以供应多独RecyclerView共同采取,在一定情景下,如viewpaper+多单列表页下有优势.客观来说,RecyclerView在一定情景下本着ListView的缓存机制做了补强和健全。

  1. 缓存不同:

1). RecyclerView缓存RecyclerView.ViewHolder,抽象但是领略吧:
View + ViewHolder(避免每次createView时调用findViewById) +
flag(标识状态);
2). ListView缓存View。

缓存不同,二者在缓存的行使上吧稍微发差别,具体来说:
ListView获取缓存的流水线:

美学原理 4

RecyclerView获取缓存的流程:

美学原理 5

1).
RecyclerView中mCacheViews(屏幕外)获取缓存时,是经过匹配pos获取目标位置的缓存,这样做的利是,当数据源数据不转移的景况下,无须重新bindView:

美学原理 6

如同一是离屏缓存,ListView从mScrapViews根据pos获取相应的缓存,但是并不曾一直行使,而是重getView(即一定会重新bindView),相关代码如下:

//AbsListView源码:line2345
//通过匹配pos从mScrapView中获取缓存
final View scrapView = mRecycler.getScrapView(position);
//无论是否成功都直接调用getView,导致必定会调用createView
final View child = mAdapter.getView(position, scrapView, this);
if (scrapView != null) {
    if (child != scrapView) {
        mRecycler.addScrapView(scrapView, position);
    } else {
                ...
    }
}

2). ListView中通过pos获取之是view,即pos–>view;
RecyclerView中通过pos获取之凡viewholder,即pos –>
(view,viewHolder,flag);
打流程图中好观看,标志flag的意向是判view是否用重新bindView,这也是RecyclerView实现有刷新的一个着力。

2.2 局部刷新

出于上文可知,RecyclerView的缓存机制真正越来越健全,但尚非算质的转,RecyclerView更可怜的亮点在于提供了片刷新的接口,通过一些刷新,就会幸免调用许多失效的bindView。

美学原理 7

(RecyclerView和ListView添加,移除Item效果相比)

结缘RecyclerView的缓存机制,看看有刷新是哪些促成之:
因为RecyclerView中notifyItemRemoved(1)为例,最终会调用requestLayout(),使整RecyclerView重新绘制,过程吧:
onMeasure()–>onLayout()–>onDraw()

里头,onLayout()为机要,分为三步:
dispathLayoutStep1():记录RecyclerView刷新前列表项ItemView的各种信息,如Top,Left,Bottom,Right,用于动画的连带测算;
dispathLayoutStep2():真正测量布局大小,位置,核心函数为layoutChildren();
dispathLayoutStep3():计算布局内外相继ItemView的状态,如Remove,Add,Move,Update等,如发必不可少实施相应的动画.

其中,layoutChildren()流程图:

美学原理 8

美学原理 9

当调用notifyItemRemoved时,会针对屏幕外ItemView做预处理,修改ItemView相应的pos以及flag(流程图中革命部分):

美学原理 10

当调用fill()中RecyclerView.getViewForPosition(pos)时,RecyclerView通过对pos和flag的优先处理,使得bindview只调用平等浅.

消指出,ListView和RecyclerView最老的别在于数据源改变时之缓存的处理逻辑,ListView是”一锅端”,将具备的mActiveViews都移入了二级缓存mScrapViews,而RecyclerView则是更灵活地针对每个View修改标志位,区分是否重新bindView。

三.结论

1、在一些景下,如界面初始化,滑动等,ListView和RecyclerView都能非常好地劳作,两者并不曾特别特别的反差:

章的开头就丢掉来了如此一个题材,微信Android客户端卡券模块,大部分UI都是盖列表页的款型显得,实现方式啊ListView,是否出必要将其替换成RecyclerView呢?

美学原理 11

答案是否认的,从性质及看,RecyclerView并没有带显著的晋升,不需要反复更新,暂无支持用动画,意味着RecyclerView优势也无太明了,没有最好可怜之吸引力,ListView已经能大好地满足工作需求。

2、数据源频繁更新的场景,如弹幕:http://www.jianshu.com/p/2232a63442d6 等RecyclerView的优势会坏明显;

更加来讲,结论是:
列表页展示界面,需要支持动画,或者屡屡更新,局部刷新,建议采取RecyclerView,更加强有力到,易扩展;其它情况(如微信卡包列表页)两者都OK,但ListView在运上会见愈有利于,快捷。