最近在解决 RecyclerView 滑动冲突问题时,遇到了使用 OnItemTouchLister
无法解决问题的场景,本篇文章将结合实际案例,重点介绍如下几个问题:
-
RecyclerView
事件分发执行流程简要分析 -
添加
OnItemTouchListener
为什么不能解决问题? -
该场景下最终的解决方案
在一个视频通话界面中,放置一个发言方列表,这个列表支持横向滑动,称为小窗列表, 处于背景的窗口称之大窗,当用户想将小窗列表中的某一个 item 切换到大窗时,可以使用手指触摸想要切换的 item, 并向上方滑动,即可将选定的小窗切换至大窗位置,而且上滑需要支持垂直向上和斜向上的方向。
解决方案
原始解决方案是为 item view 设置 OnTouchListener
方法, 在其 onTouch()
方法中的 ACTION_MOVE
事件中判断 dy (Y 坐标偏移量) 是否大于某个阈值。
遇到的问题
遇到的问题是当在 item 斜向上滑动时,item view 收到的 ACTION_MOVE
事件的 dy 总是特别小,即使你确定已经滑动了很多时
-
该问题定位为 在横向滑动时,RecyclerView 与 item 发生了嵌套滑动冲突
-
怀疑是 RecyclerView 消费了部分滑动事件,导致 item view 收到的滑动距离特别小。
通过翻阅源码发现,RecyclerView 内部提供了 OnItemTouchListener
, 介绍如下:
/**
* An OnItemTouchListener allows the application to intercept touch events in progress at the
* view hierarchy level of the RecyclerView before those touch events are considered for
* RecyclerView's own scrolling behavior.
*
* <p>This can be useful for applications that wish to implement various forms of gestural
* manipulation of item views within the RecyclerView. OnItemTouchListeners may intercept
* a touch interaction already in progress even if the RecyclerView is already handling that
* gesture stream itself for the purposes of scrolling.</p>
*
* @see SimpleOnItemTouchListener
*/
public static interface OnItemTouchListener{
/**
* Silently observe and/or take over touch events sent to the Re