美文网首页
RecycleView的复用

RecycleView的复用

作者: 我要离开浪浪山 | 来源:发表于2023-05-13 15:53 被阅读0次

1、布局复用

6f9acbf4eda88f1ce546eaf7958c6f4.png

2、RecyclerView的多级缓存机制

RecyclerView一共有四级缓存,分别是:

1、一级缓存:mAttachedScrap 和 mChangedScrap,用来缓存还在屏幕内的 ViewHolder。
2、二级缓存:mCachedViews ,用来缓存移除屏幕之外的 ViewHolder,默认大小为2。
3、三级缓存:ViewCacheExtension,开发给用户的自定义扩展缓存,需要用户自己管理 View 的创建和缓存。(不常用)
4、四级缓存:RecycledViewPool,ViewHolder的缓存池,默认大小为5。

3、ViewHolder

  • 从缓存池中 复用 ViewHolder :需要调用 onBindViewHodler
  • 从 CacheView 复用: 不用调用 onBindViewHodler
  • 从缓存中没有拿到 ViewHolder: onCreate onBind

4、缓存复用 --> 保存的是什么??

  • onCreateViewHolder
  • onBindViewHolder

5、RecyclerView的滑动回收复用机制

假设屏幕内可以显示10个ViewHolder(2行5列),所以一开始会创建10个ViewHolder用于显示,创建5个ViewHolder放入缓存池中,在上滑时会将滑入屏幕上方的ViewHolder首先放入二级缓存中,由于默认大小为2,所以多余的3个ViewHolder会被回收到四级回收中,此时一级缓存中有10个ViewHolder,二级缓存中有2个ViewHolder,四级缓存中有3个ViewHolder。继续上滑的过程中,一级缓存需要显示15个ViewHolder,此时需要从四级缓存中取出5个ViewHolder,由于只有3个ViewHolder,所以需要创建两个缓存。上滑完毕后,5个一级缓存的ViewHolder移出屏幕,其中2个一级缓存的ViewHolder会被存入二级缓存,之前的2个二级缓存的ViewHolder 和 3个一级缓存的ViewHolder会被清空数据后存至四级缓存中。

6、RecyclerView为什么要预布局

因为RecyclerView要执行预测动画。

当Adapter发生变化时,RecyclerView会让LayoutManager进行两次布局:

  • 第一次为预布局,根据Adapter的notify信息即可知道那些item即将变化了,将不可见的表项也会加载到布局中。
  • 第二次为实际布局,也就是变化后的布局。

只要根据前后布局的变化,就可以得出应该执行什么动画。

7、RecyclerView和ListView的区别

  • 布局效果:RecyclerView支持线性布局、表格布局、瀑布流布局,ListView支持线性布局。
  • 缓存区别:RecyclerView有四级缓存,ListView仅有两级缓存。
  • 局部刷新:RecyclerView自身支持局部刷新,ListView本身不支持局部刷新。

8、RecyclerView第一次layout时,会发生预布局pre-layout吗?

第一次布局时,并不会触发pre-layout。pre-layout只会在每次notify change时才会被触发,目的是通过saveOldPosition方法将屏幕中各位置上的ViewHolder的坐标记录下来,并在重新布局之后,通过对比实现Item的动画效果。
比如以下效果:

403331589e154e874f6c32e59d75752.png

9、如果自定义LayoutManager需要注意什么?

1、确定布局方式:自定义LayoutManager需要确定布局方式,例如是线性布局、网格布局、瀑布流布局等。
2、实现布局算法:根据布局方式,需要实现相应的布局算法,例如线性布局需要计算每个子View的位置和大小,网格布局需要计算每个子View的行列位置和大小等。
3、处理滑动:自定义LayoutManager需要处理RecyclerView的滑动事件,包括手动滑动和惯性滑动。
4、处理Item动画:自定义LayoutManager需要处理RecyclerView的Item动画,包括添加、删除、移动等操作的动画效果。
5、处理复用:自定义LayoutManager需要处理RecyclerView的复用机制,包括回收和重用子View。
6、考虑性能:自定义LayoutManager需要考虑性能问题,尽量减少不必要的计算和内存消耗,避免卡顿和OOM等问题。
7、兼容性:自定义LayoutManager需要考虑兼容性问题,尽量兼容不同版本的Android系统和不同的设备屏幕尺寸。

10、ViewHolder何时被缓存到RecycledViewPool中?

主要有以下2种情况:

1、当ItemView被滑动出屏幕时,并且CachedView已满,则ViewHolder会被缓存到RecycledViewPool中;
2、当数据发生变动时,执行完disappearrance的ViewHolder会被缓存到RecycledViewPool中;

11、CachedView和RecycledViewPool的关系

当一个ItemView被滑动滚出屏幕之后,默认会先被保存在CachedView中。CachedView的默认大小为2,可以通过 setItemViewCacheSize 方法修改它的值。当CachedView已满后,后续有新的ItemView从屏幕内滑出时,会迫使CachedView根据FIFO规则,将之前的缓存的ViewHolder转移到RecycledViewPool中,

效果可以参考下图:

3ee0c669914d3f033bccb4b1fe68ceb.png

RecycledViewPool默认大小为5,可以通过以下方式修改RecycledViewPool的缓存大小:

RecyclerView.getRecycledViewPool().setMaxRecycledViews(int viewType, int max);

12、CachedView和RecycledViewPool两者区别

缓存到CachedView中的ViewHolder并不会清理相关信息(比如position、state等),因此刚移出屏幕的ViewHolder,再次被移回屏幕时,只要从CachedView中查找并显示即可,不需要重新绑定(bindViewHolder)。

而缓存到RecycledViewPool中的ViewHolder会被清理状态和位置信息,因此从RecycledViewPool查找到ViewHolder,需要重新调用bindViewHolder绑定数据。

13、你是从哪些方面优化RecyclerView的?

主要可以从以下几个方面对RecyclerView进行优化:

  • 使用ViewHolder模式:ViewHolder模式可以减少创建View的次数,提高RecyclerView的性能。
  • 使用DiffUtil:DiffUtil可以帮助RecyclerView计算出数据集的差异,从而只更新需要更新的部分,减少不必要的刷新。
  • 使用分页加载:将数据分页加载可以减少一次性加载大量数据的压力,提高RecyclerView的性能。
  • 使用图片缓存:使用图片缓存可以减少重复加载图片的次数,提高RecyclerView的性能。
  • 使用RecyclerView的优化方法:如设置固定大小、使用setHasFixedSize()方法、使用LayoutManager等方法可以提高RecyclerView的性能。

14、多条目固定头部和卡片上下左右拖拽


参考:https://zhuanlan.zhihu.com/p/150105789?from_voters_page=true

相关文章

网友评论

      本文标题:RecycleView的复用

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