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

一. 背景

PS:相关知识:
ListView与RecyclerView缓存机制原理差不离相似,如下图所示:

美学原理 1

滑动进度中,离屏的ItemView即被回收至缓存,入屏的ItemView则会优先从缓存中获取,只是ListView与RecyclerView的落到实处细节有差别.(那只是缓存使用的当中3个光景,还有如刷新等)

2.1 缓存机制比较

  1. 层级不一样:
    RecyclerView比ListView多两级缓存,扶助七个离ItemView缓存,扶助开发者自定义缓存处理逻辑,援救全数RecyclerView共用同3个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完成部分刷新的贰当中央。

三.结论

壹 、在一些光景下,如界面早先化,滑动等,ListView和RecyclerView都能很好地劳作,两者并从未十分大的差距:

小说的起来便抛出了这样1个难点,微信Android客户端卡券模块,大多数UI都以以列表页的方式显得,完毕格局为ListView,是还是不是有必不可中校其替换到RecyclerView呢?

美学原理 7

答案是或不是认的,从性质上看,RecyclerView并从未推动显明的升级,不须求频仍更新,暂不援助用动画,意味着RecyclerView优势也不太明了,没有太大的重力,ListView已经能很好地满意工作须要。

② 、数据源频仍更新的意况,如弹幕:http://www.jianshu.com/p/2232a63442d6 等RecyclerView的优势会特别通晓;

愈来愈来讲,结论是:
列表页展现界面,要求帮忙动画,也许屡屡更新,局地刷新,建议利用RecyclerView,更加强大完善,易扩张;其余情状(如微信卡包列表页)两者都OK,但ListView在运用上会特别惠及,快速。

二. 正文

2.2 局地刷新

由上文可见,RecyclerView的缓存机制真正越来越完善,但还不算质的变型,RecyclerView更大的优点在于提供了有个别刷新的接口,通过一些刷新,就能防止调用许多空头的bindView。

美学原理 8

(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()流程图:

美学原理 9

美学原理 10

当调用notifyItemRemoved时,会对显示器内ItemView做预处理,修改ItemView相应的pos以及flag(流程图中深红部分):

美学原理 11

当调用fill()中RecyclerView.getViewForPosition(pos)时,RecyclerView通过对pos和flag的预处理,使得bindview只调用三遍.

亟需提出,ListView和RecyclerView最大的分别在于数据源改变时的缓存的拍卖逻辑,ListView是”一锅端”,将有所的mActiveViews都移入了二级缓存mScrapViews,而RecyclerView则是进一步灵活地对种种View修改标志位,区分是不是重新bindView。