CoordinatorLayout+RecyclerView加载更多时自动滑动的问题
June 15, 2018
记录一下CoordinatorLayout
+RecyclerView
组合联动时,滑到底部触发加载更多并通过notifyItemRangeInserted
添加数据时,RecyclerView
会顺着继续滑动的问题。
问题 GIF
使用CoordinatorLayout
联动RecyclerView
的情况下(普通情况不会),加载更多是通过设置多Type
的方式注入adapter
实现的。当快速滑动RecyclerView
时,通过notifyItemRangeInserted
插入数据到尾部,则会发生下图所示的情况。
解决之路
焦点问题?
在大多数场景是没有使用CoordinatorLayout
的,正常的使用RecyclerView
是不会出现这种现象,所以一开始就觉得是CoordinatorLayout
嵌套的焦点问题,焦点被RecyclerView
抢夺导致自动滑动(Ps:以前见多了各种ScrollView
嵌套的焦点问题)。所以给CoordinatorLayout
做了焦点拦截,直接在布局文件设置属性
android:descendantFocusability="blocksDescendants"
但是并没有解决问题
之后试了半天布局修改,例如android:focusable="true" android:focusableInTouchMode="true"
等都解决不了问题,只能上网搜搜了。。。
positionStart?
搜到的第一个类似问题,附带个链接 -> Link
这位码友也是遇到类似自动滑动的问题,也是添加数据后触发,只不过他的情况是他有个多type
的头部,所以调用notifyItemRangeInserted
时的positionStart
得+1
,这也提醒我们打代码的时候得多注意,很多神奇的 bug 都是这样来的。。。
也不是解决方案
RecyclerView 设计初衷?
再搜到一个类似问题,再附带链接 -> Link
这次这位码友的情况跟我挺相似的,也是利用多type
实现footer
,利用这个footer
实现加载更多的功能,同样插入数据会自动滑动。最佳回答是这样说的:
该码友在有
footer
的时候调用notifyItemRangeInserted(0, list.size())
时,由于footer
是唯一存在的第一条item
,RecyclerView
为了保持用户视觉体验、能继续看到footer
,所以自动滑动到footer
的位置。推荐该码友在list.size() == 0
时候调用notifyDataSetChanged()
代替
这一现象确实存在,也是平时需要注意的点,但也不是这次的解决方案
解决!!!
再之后找不到相关的问题了,也是自己看了下RecyclerView
的源码,找到了个方法
recyclerview.stopScroll()
所以最后也是投机取巧的暂时解决这个问题,在插入数据之前停止滚动
(暂时无法从NestedScroll
联动滑动机制解决这个问题,如果有大佬知道这个问题解决方案恳请告知一声,下方评论或 Email 我都可以,谢谢)
recyclerview.stopScroll();
adapter.addList(list);
public void addList(List<Object> list) {
final int index = mList.size();
mList.addAll(list);
notifyItemRangeInserted(index, list.size());
}
— Evil Mouth