本文以通俗的语言,记录在阅读RecyclerView源码时的一些心得🤔。

添加view的过程

  1. 在使用recyclerView的setAdapter方法设置adapter时,会调用RecyclerView的requestLayout()方法,进而执行measure、layout等生命方法;
  2. 何时添加的子view(adapter里面的一堆):在RecyclerView执行layout时,实际会调用LayoutManager的onLayoutChildren()方法去layout子view,如LinearLayoutManager,方法堆栈:onLayoutChildren()->fill()->layoutChunk()。
  3. 滚动时如何判断需要add一个子view:核心方法:updateLayoutState(),以向右滑动为例:①拿到当前最左边的view(getChildClosestToStart()),一般就是child0;②然后计算还可以向左滑动多远的距离才需要add一个view,getDecoratedStart()方法:计算最左边的子view在RecyclerView中的位置(getLeft()+margin)。经过计算之后可以知道:是否需要添加新的子view来填充RecyclerView。

View的复用

下面描述RecyclerView是如何对view进行复用的。
一、RecyclerView的缓存

  1. 一级缓存:mAttachedScrap
    mAttachedScrap中的view不需要 重新bindView 。ScrapView主要用于对于屏幕内可见的ChildView的缓存,缓存中的ViewHolder不需要重新Bind,缓存时机是在onLayout的过程中,并且用完即清空,里面的view只是被detach,不会被remove,在onLayout时会使用;
  2. 二级缓存:mCacheViews
    mCacheViews也不需要重新bind,里面的view是被remove过的,缓存滑动时即将离开RecyclerView的ViewHolder;
  3. 三级缓存:mViewCacheExtension
  4. 四级缓存:mRecyclerPool

二、view查找过程
在RecyclerView的view不足时,需要addView,view的查找过程如下,一层层降级获取可使用的view:

  1. 优先从 mAttachedScrap 列表中查找,查找的position必须和列表中某个holder的position 完全一致 ,即:要查找的holder和该缓存里面的某个holder达到完全一致的状态;
  2. mCachedViews 列表中查找,也需要position完全一致匹配。mCachedViews默认最大缓存为2,当大于该值时,将holder缓存移至RecycledViewPool;
  3. mAdapter.hasStableIds()为true时,否则转4:从mAttachedScrap、mCachedViews列表中查找viewType相同的holder,在1、2都失败的情况下,说明position完全匹配失败,这时候需要找到viewType相同的holder缓存;
  4. 从RecycledViewPool里面根据viewType查找缓存的holder。
    说明 :RecycledViewPool针对每一种viewType有一个缓冲池,池子大小默认为5,当某一种viewType的holder在RecycledViewPool中的缓存数量大于最大值时,会被丢弃;
  5. 缓存全部无法命中,则调用Adapter.createViewHolder新建holder。
本文以通俗的语言,记录在阅读RecyclerView源码时的一些心得????。添加view的过程在使用recyclerView的setAdapter方法设置adapter时,会调用RecyclerView的requestLayout()方法,进而执行measure、layout等生命方法;何时添加的子view(adapter里面的一堆):在RecyclerView执行layout时,实际会调用L...
RecyclerView 的功能强大之处就不用说了,但是相比于list view 来说,它也有些小缺点,比如:没有了间隔线divider,没有 add Header View add Footer View 等方法,所以用起来不是那么方便。今天主要完成 RecyclerView add Header View add Footer View 方法。 运行效果如下:第一步:自定义 RecyclerView ,代码如下:public
不多说直接上代码 先是 RecyclerView 的配置 m RecyclerView .setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)); m RecyclerView .setHasFixedSize(true); mAd... LayoutManager: 1.get View ForPosition():是Recycler的方法,在需要获取新的 View 时直接申请,返回的 View 可能是之前回收的垃圾 View ,也可能是new出来的新 View RecyclerView 完成); 取 View 时,
项目 有这么一个需求: 要做一个类似相册功能,多张相册滑动,但是每个页面 可能有多张图片组成,位置不确定,需要后台确定. 看完需求后,想都不用想直接使用 recyclerview ,item的根布局为Relativelayout,通过LayoutParams和后台给的数据确定位置和大小,最后 add View 添加 view Group :效果和预想的一样 但是最后滑动多张后,发现点击空白处,实际上对应其他...
利用Window. add View (),滑动时updatePosition 利用 RecyclerView . add View (),滑动时改变漂浮控件float View 的layoutParams.margin 第一种,利用Window更新位置稍微复杂点,放弃。 第二种,Recycl... 1.1、从上图 看出:Recycle View 的缓存从上到下分为四层:scrap、cache、 View CacheExtension、Recycle View Pool 1.2、Recycle View 缓存的对象是 View Holder,而Recycle View 复用 的对象也是 View Holder 1.3、Recycler负责管理和缓存所有的 View Holder。 2、四级缓存介绍: 2.1、scrap: 从图 可以看出,scrap是用来缓存正在显示的 View H.
Android RecyclerView Android RecyclerView 支持 add Header View add Footer View 和loadMore。 ##代码设置 添加 head View MfRecycyler View m RecyclerView ; m RecyclerView . add Header View (header View ); 添加 footer View m RecyclerView . add Footer View (footer View ); 设置empty View m RecyclerView .setEmpty View (empty View ); RecyclerView 滑动到底部m RecyclerView . add OnScrollListener(new OnRcvScrollListener(OnRcvScrollListener.LAYOUT_MANAGERTYPE.LINEAR,
第一篇,给recycle view 添加 header,footer,empty view 。 最近有开发一个列表,这个列表需要 添加 header和footer的功能。记录一下,避免每次开发都去查找相关代码。 代码示例: (1)adapter: public class MessageCenterAdapter extends Recycle...
RecyclerView 作为List View 的替代者有着较好的性能提升,但是有些List VIew 的常用功能却没有提供比如 add Header View add Footer View ; 作为替代方案,可以通过自定义的Adapter来实现 add Header View add Footer View 功能,代码如下: public class HeaderAdapter extends RecyclerView .
文章目录前言使用方式(kotlin)自定义Recycle View (kotlin)腾讯bugly 示例代码疏漏地方引用 有时候我们在使用Recycle View 的时候需要在没有数据的时候设置empty View 。这里通过对Recycle View 进行拓展来设置empty View .本质上是通过有数据时候隐藏Recycle View 显示empty View ,无数据时候通过隐藏empty View 显示Recycle View 来处理的。本例参考腾讯Bugly的代码,但是示例代码有疏漏,所以这里给出原因及解决方式。 使用方式(
<h3>回答1:</h3><br/>在使用 Android 的 NestedScroll View 嵌套 RecyclerView 的过程 ,出现了数据无法 复用 缓存的问题,这是因为 RecyclerView 复用 机制并不适用于 NestedScroll View 的嵌套情况。 NestedScroll View 包含的 RecyclerView 实际上是作为一个子 View 的形式出现的,而每一个子 View 的布局和数据都是不同的,所以 RecyclerView 无法反复利用之前已经使用过的缓存。这会导致在滑动过程 不断创建新的 View Holder,从而降低应用程序的性能。 为了解决这个问题,可以将 RecyclerView 操作放到调用 NestedScroll View 的 onScrollChanged() 方法里面,以确保它的缓存机制被正确使用。另外,为 RecyclerView 设置setHasFixedSize(true)属性可以使性能有一些提升。 最好的解决方案是使用单个 RecyclerView 以及多个 Adapter 对其进行管理。这种方法可以让您更好地控制与管理 RecyclerView 的数据,在保证 NestedScroll View 能够适当地管理视图树的同时,确保 RecyclerView 没有内存和性能问题。 <h3>回答2:</h3><br/>Android RecyclerView 是一个非常高效的列表控件,它可以使用 View Holder机制对视图进行缓存,减少频繁更新视图的开销,但是在使用NestedScroll View 嵌套 RecyclerView 时,却会出现数据无法 复用 缓存的问题。 这是因为NestedScroll View 默认会将 RecyclerView 的所有子视图都展开,导致 RecyclerView 所有的子视图都处于可见状态,无法被缓存。因此,当列表滑动时, RecyclerView 会重新实例化缓存的 View Holder,以展示新的子视图。这个过程会消耗大量的内存和CPU,导致 RecyclerView 变得非常缓慢,甚至会导致OOM崩溃等问题。 为了解决这个问题,我们需要使用一些技巧来保证 RecyclerView 的子视图只有在需要的时候才被展开。一种解决方案是通过设置NestedScroll View 的fill View port属性为false,使NestedScroll View 不将 RecyclerView 的所有子视图都展开。这样做可以让 RecyclerView 正确地使用 View Holder机制,但是在滑动过程 ,子视图的高度会频繁变化,导致列表的抖动,用户体验也会受到一定的影响。 另一种解决方案是使用 RecyclerView 的setRecycled View Pool()方法,为 RecyclerView 缓存一个视图池,这个视图池可以在 RecyclerView 的所有嵌套层级间共享,让所有子视图都可以被重复使用。这个方案的优点是可以减少在滑动过程 子视图高度变化带来的问题,但是需要在代码 进行额外的编写。 总之,NestedScroll View 嵌套 RecyclerView 在使用时要注意子视图的缓存问题,需要通过调整布局属性或使用 RecyclerView 的视图池等技巧来解决。 <h3>回答3:</h3><br/>Android的嵌套滑动规范是在Android 5.0(API level 21) 引入的,用于使父 View 和子 View 之间的滑动效果更加协调。而NestedScroll View RecyclerView 都是Android 常用的滑动控件,但是在嵌套使用的过程 RecyclerView 的数据无法 复用 缓存,这是为什么呢? 首先,我们需要了解 RecyclerView 的缓存机制。 RecyclerView 使用三种缓存机制:首先是 View Holder缓存,它可以在滑动时快速重新绑定已经存在的 View Holder对象;其次是 View 缓存,它缓存了滑出屏幕的 View ,可以加速滑动时的UI响应;最后是Bitmap缓存,它用于缓存在 RecyclerView 的图像。 然而,在嵌套使用NestedScroll View RecyclerView 时, RecyclerView 的缓存机制无法发挥作用。这是因为NestedScroll View 将滑动事件先处理,然后再将滑动事件交给 RecyclerView 处理,这会重新调用 RecyclerView 的Adapter 的get View ()方法,导致 RecyclerView 的缓存被清空。因此, RecyclerView 的数据无法 复用 缓存,会造成性能上的损失。 为了解决这个问题,可以采取以下措施: 1.不要嵌套滑动控件:尽量避免使用NestedScroll View RecyclerView 等嵌套滑动控件。 2.使用LayoutManager:使用LayoutManager可以缓存 RecyclerView View Holder对象,加速滑动过程 的UI响应。 3.自定义LayoutManager:自定义LayoutManager可以对滑动速度、滑动方向等进行优化,提高 RecyclerView 的性能。 4.使用分组显示:对 RecyclerView 的数据进行分组,将分组内的数据合并成一张图片,然后将图片缓存起来,这样可以减少 RecyclerView 的刷新次数。 总的来说,NestedScroll View RecyclerView 的嵌套使用会导致 RecyclerView 的缓存无法 复用 ,降低 RecyclerView 的性能,因此需要采取一些措施来解决这个问题。使用LayoutManager、自定义LayoutManager、分组显示等方法可以优化 RecyclerView 的性能,提高用户体验。