RecycleView 嵌套卡顿
RecycleView 嵌套卡顿
https://blog.csdn.net/qq_30983519/article/details/81280274
- 共用 RecycledViewPool,holder. innerRecyclerView. setRecycledViewPool (viewPool)
2. setInitialPrefetchItemCount (int) 来优化嵌套时预加载性能 - 设置 recycleview 的子项缓存 rv. setItemViewCacheSize (200);
- rv. setHasFixedSize (true);
- recyclerview 嵌套 recyclerview 的时候, adapter 全局变量
NestedScrollView 嵌套 recyclerView
NestedScrollview 和 recycler View 嵌套的时候, recyclerview 的缓存机制失效了, 这种情况有没有什么好的解决办法呢?
NestedScrollView 传递给子 View 的测量模式为 UNSPECIFIED,RecyclerView 在 UNSPECIFIED 的测量模式下,会不限制自身的高度,即 RecyclerView 的窗口高度将会变成所有 item 高度累加后加上 paddding 的高度。因此,表现出来就是 item 一次性全部加载完成。
这样做在 RecyclerView 的 item 数量较少的时候可能没什么问题,但是如果 item 数量比较多,随之带来的性能问题就会很严重。
推荐使用 RecyclerView 的多样式布局实现,毕竟 RecyclerView 自带滑动,没必要外层套一个 ScrollerView 或者 NestedScrollView
必须嵌套,解决方案:
懒饭详情页嵌套效果仿写(View/Compose 实现) - 简书
问题本质上其实就是因为高度不确定导致复用失效了,那其实指定 RecyclerView 的高度即可,例如屏幕的高。
[[NestedScrollingParent]]
1 |
|
实例
1 |
|
上面的代码是针对嵌套滚动的情况进行处理的。根据代码的逻辑,可以理解如下:
onNestedPreScroll()
方法用于处理嵌套滚动前的预处理。当嵌套滚动发生时,会调用该方法。参数说明如下:target
: 嵌套滚动的目标视图。dx
: 水平方向上的滚动距离。dy
: 垂直方向上的滚动距离。consumed
: 用于传递消耗的滚动距离的数组。type
: 滚动事件类型。
在代码中,首先判断当前滚动的位置
scrollY
是否小于scrollViewHeadHeight
(一个预设的阈值)。如果小于该阈值,表示需要对滚动进行处理。- 如果
scrollY + dy
小于scrollViewHeadHeight
,直接进行滚动并消耗全部的垂直滚动距离dy
,将其存入consumed
数组中。 - 如果
scrollY + dy
大于scrollViewHeadHeight
,则需要将滚动限制在scrollViewHeadHeight
的位置,即将滚动距离限制为scrollViewHeadHeight - scrollY
,并将此消耗的滚动距离存入consumed
数组中。
fling()
方法用于处理滑动手势的快速滚动。当手指快速滑动屏幕时,会调用该方法。参数说明如下:velocityY
: 垂直方向上的滑动速度。
在代码中,首先判断当前滚动的位置
scrollY
是否小于scrollViewHeadHeight
。- 如果小于该阈值,表示需要对滚动进行处理。
- 如果
scrollY + dy
小于等于scrollViewHeadHeight
,直接调用父类的super.fling(velocityY)
方法进行滚动。 - 如果
scrollY + dy
大于scrollViewHeadHeight
,则需要将滚动限制在scrollViewHeadHeight
的位置,即将滚动距离限制为scrollViewHeadHeight - scrollY
,并将此消耗的滚动距离存入scrollViewNeedScrollY
。 - 接下来,根据滚动速度
velocityY
计算出scrollViewNeedScrollY
所对应的速度scrollViewNeedVelocity
。 - 如果
velocityY
大于 0,表示向上滑动,调用父类的super.fling(scrollViewNeedVelocity)
方法进行滚动。 - 如果
velocityY
小于等于 0,表示向下滑动,调用父类的super.fling(-scrollViewNeedVelocity)
方法进行滚动。 - 然后,剩余的滚动距离为
dy - scrollViewNeedScrollY
,根据剩余距离计算出对应的速度recyclerViewNeedVelocity
。 - 最后,通过
getChildRecyclerView(this)?.fling(0, recyclerViewNeedVelocity)
将剩余的滚动事件交给嵌套的 RecyclerView 处理。
这段代码的目的是在特定的条件下对滚动和快速滑动进行限制和分发,以实现特定的滚动效果和交互行为。具体的实现细节和逻辑可能还需要结合其他代码来全面理解其功能和效果。