关于NestedScrollView和Paging3一起使用的bug,其实更应该说是NestedScrollView和RecyclerView一起使用时产生的“问题”。
Bug还原
使用NestedScrollview嵌套竖向的RecyclerView时,同时使用Paging3分页加载库实现RecyclerView的分页加载。NestScrollView最终导致Paging3分页加载循环加载,即进入页面后,会不断进行分页加载,直到所有页面加载完成,快速连续的分页加载导致页面滑动卡顿。
上图中,NestedScrollView嵌套一个RecyclerView和其他控件,进入页面后,Paging3的adpter预设一页8个Item,所以第一次应只加载8个Item,只有当屏幕滚动到第8个Item时触发分页加载,事实上在进入页面后,就会不断触发Paging3的分页加载,第二张图显示第9-16号Item被加载,之后每页的Item都被分页加载出来。
组件简介
NestedScrollView,即支持嵌套滑动的ScrollView,被官方推荐和RecyclerView一起使用解决嵌套滑动的问题,可以在NestedScrollView中嵌套RecyclerView+其他控件,解决ScrollView会出现的滑动冲突问题,但NestedScrollView本身就有很多问题,常见问题见NestedScrollView、RecycleView、ViewPager 等布局方面的常见问题汇总,及解决
Paging3,Android Jetpack的一部分,Paging库可帮助您加载和显示来自本地存储或网络中更大的数据集中的数据页面。Paging库其中一个功能就是“可配置的 RecyclerView 适配器,会在用户滚动到已加载数据的末尾时自动请求数据”。
原因猜测:
这个Bug的原因猜测一下很简单,就是被NestedScrllView嵌套的RecyclerView会一次性加载完所有的Item,即一次性走完所有Item的onCreateViewHolder(),同时Paging3的分页加载条件是滑动到最后几个Item时,进行分页加载,即在最后几个Item执行onCreateViewHolder()时加载新一页的数据,这就导致了一个NestedScrollView和Paging3循环加载的BUG:NestedScrollView自动加载完一页数据,触发paging3加载新一页数据,新的数据到来又出发NestedScrollerView自动加载完一页数据,如此循环,导致最终一次性把所有数据加载完毕。
解决方案
不使用NestedScrollView嵌套RecyclerView
- 如果需要和RecyclerView一起滑动的控件复杂度不高,推荐直接使用RecyclerView自己添加 Header和Footer
- 如果其它控件复杂度较高,推荐使用CoordinatorLayout+AppBarLayout+CollapsingToolbarLayout实现其他控件和RecyclerView的一起滑动。可以把其他控件放在CollapsingToolbarLayout中,RecyclerView放在CoordinatorLayout中