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在利用上相会越来越惠及,神速。