美文网首页
recycleview 复用

recycleview 复用

作者: couriravant | 来源:发表于2019-08-22 16:32 被阅读0次
    image.png image.png

    mChangedScrap : 用来保存RecyclerView做动画时,被detach的ViewHolder。
    mAttachedScrap : 用来保存RecyclerView做数据刷新(notify),被detach的ViewHolder
    mCacheViews : Recycler的一级ViewHolder缓存。
    RecyclerViewPool : mCacheViews集合中装满时,会放到这里。

    从Recycler中获取一个ViewHolder的逻辑:

    即大致步骤是:

    1.如果执行了RecyclerView动画的话,尝试根据position从mChangedScrap集合中寻找一个ViewHolder
    2.尝试根据position从scrap集合、hide的view集合、mCacheViews(一级缓存)中寻找一个ViewHolder
    3.根据LayoutManager的position更新到对应的Adapter的position。 (这两个position在大部分情况下都是相等的,不过在子view删除或移动时可能产生不对应的情况)
    4.根据Adapter position,调用Adapter.getItemViewType()来获取ViewType
    根据stable id(用来表示ViewHolder的唯一,即使位置变化了)从scrap集合和mCacheViews(一级缓存)中寻找一个ViewHolder,可以用来防止刷新过程中出现的闪烁和焦点变化,参考:https://blog.csdn.net/qq_36523667/article/details/78736015
    https://cloud.tencent.com/developer/article/1146916

    5.根据position和viewType尝试从用户自定义的mViewCacheExtension中获取一个ViewHolder
    6.根据ViewType尝试从RecyclerViewPool中获取一个ViewHolder
    7.调用mAdapter.createViewHolder()来创建一个ViewHolder
    8.如果需要的话调用mAdapter.bindViewHolder来设置ViewHolder。
    调整ViewHolder.itemview的布局参数为Recycler.LayoutPrams,并返回Holder

    image.png

    分为三种情况
    1.从无到有,会create出新的view
    2.整体刷新
    1)存储旧的:所有的view会进入scrap状态(ViewHolder被标记为FLAG_TMP_DETACHED状态,并且其itemview的parent被设置为null),调用detachAndScrapAttachedViews把所有的view存储到mAttachedScrap中
    2)获取缓存:LinearLayoutManager会当前布局子View的位置向Recycler要一个子View,即调用到tryGetViewHolderForPositionByDeadline(position..)
    这个方法会尝试根据position从mAttachedScrap、hide的view集合、mCacheViews(一级缓存)中寻找一个ViewHolder,这种情况大部分是从mAttachedScrap返回复用的。
    3.滚动复用
    在这种情况下滚出屏幕的View会优先保存到mCacheViews, 如果mCacheViews中保存满了,就会保存到RecyclerViewPool中。

    image.png

    通过了解RecyclerView的四级缓存,我们可以知道,RecyclerView最多可以缓存 N(屏幕最多可显示的item数) + 2 (屏幕外的缓存) + 5*M (M代表M个ViewType,缓存池的缓存),只有RecycledViewPool找到时才会重新调用 bindViewHolder。

    对比listView:

    image.png

    1.层级不同:
    RecyclerView比ListView多两级缓存,支持多个离ItemView缓存,支持开发者自定义缓存处理逻辑,支持所有RecyclerView共用同一个RecyclerViewPool(缓存池)。
    具体来说: ListView(两级缓存):
    2.缓存机制的不同:
    mActiveViews和mAttachedScrap功能相似,意义在于快速重用屏幕上可见的列表项ItemView,而不需要重新createView和bindView;
    2). mScrapView和mCachedViews + mReyclerViewPool功能相似,意义在于缓存离开屏幕的ItemView,目的是让即将进入屏幕的ItemView重用.
    3). RecyclerView的优势在于a.mCacheViews的使用,可以做到屏幕外的列表项ItemView进入屏幕内时也无须bindView快速重用;b.mRecyclerPool可以供多个RecyclerView共同使用,在特定场景下,如viewpaper+多个列表页下有优势.客观来说,RecyclerView在特定场景下对ListView的缓存机制做了补强和完善。

    refer:
    https://juejin.im/post/5c1369cff265da613b6fa87f#heading-2
    https://zhooker.github.io/2017/08/14/%E5%85%B3%E4%BA%8ERecyclerview%E7%9A%84%E7%BC%93%E5%AD%98%E6%9C%BA%E5%88%B6%E7%9A%84%E7%90%86%E8%A7%A3/
    https://www.jianshu.com/p/193fb966e954

    相关文章

      网友评论

          本文标题:recycleview 复用

          本文链接:https://www.haomeiwen.com/subject/awwnsctx.html