需求
在用户上下滑动列表时,检测用户是否左右滑动,如果是左右滑动需要根据左右滑动的距离绘制当前item的显示效果,还要判断有没有超出y轴范围;
解决思路
1.在item的itemView添加onTouchListener事件,事件无法正常传递
2.使用SimpleOnItemTouchListener实现效果✅
SimpleOnItemTouchListener类的介绍
/**
* Silently observe and/or take over touch events sent to the RecyclerView
* before they are handled by either the RecyclerView itself or its child views.
*
* <p>The onInterceptTouchEvent methods of each attached OnItemTouchListener will be run
* in the order in which each listener was added, before any other touch processing
* by the RecyclerView itself or child views occurs.</p>
*
* @param e MotionEvent describing the touch event. All coordinates are in
* the RecyclerView's coordinate system.
* @return true if this OnItemTouchListener wishes to begin intercepting touch events, false
* to continue with the current behavior and continue observing future events in
* the gesture.
*
* 在RecyclerView本身或其子视图处理发送到RecyclerView的触摸事件之前,静默地观察和/或接管这些事件。
* 在RecyclerView本身或子视图进行任何其他触摸处理之前,每个附加的OnItemTouchListener的onInterceptTouchEvent方法将按照添加每个侦听器的顺序运行。
* 参数:
* e–描述触摸事件的MotionEvent。所有坐标都在RecyclerView的坐标系中。
* 返回:
* 如果此OnItemTouchListener希望开始拦截触摸事件,则为true;如果为false,则继续当前行为并继续 * 观察手势中的未来事件。
*/
boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
/**
* Process a touch event as part of a gesture that was claimed by returning true from
* a previous call to {@link #onInterceptTouchEvent}.
*
* @param e MotionEvent describing the touch event. All coordinates are in
* the RecyclerView's coordinate system.
*
* 将触摸事件作为手势的一部分进行处理,该手势是通过从上一次对onInterceptTTouchEvent的调用返回true来声明的。
* 参数:
* e–描述触摸事件的MotionEvent。所有坐标都在RecyclerView的坐标系中。
*/
void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e);
/**
* Called when a child of RecyclerView does not want RecyclerView and its ancestors to
* intercept touch events with
* {@link ViewGroup#onInterceptTouchEvent(MotionEvent)}.
*
* @param disallowIntercept True if the child does not want the parent to
* intercept touch events.
* @see ViewParent#requestDisallowInterceptTouchEvent(boolean)
*
* 当RecyclerView的子级不希望RecyclerView及其祖先使用ViewGroup.oInterceptTouchEvent(MotionEvent)截取触摸事件时调用。
* 参数:
* disallowIntercept–如果孩子不希望父母拦截触摸事件,则为True。
* 另请参阅:
* ViewParent.requestDisableInterceptTouchEvent(布尔值)
*/
void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept);
通过以上方法介绍我们只需要重写onInterceptTouchEvent来实现需求;
重写onInterceptTouchEvent
通过返回的MotionEvent类,我们可以跟onTouchListener一样识别用户手势,例如:MotionEvent.ACTION_MOVE、MotionEvent.ACTION_UP等,也可以获取当前的x、y轴坐标计算位移;
我们还可以通过返回的RecyclerView搭配MotionEvent来获取当前位置的itemView:
object : SimpleOnItemTouchListener() {
override fun onInterceptTouchEvent(rv: RecyclerView, event: MotionEvent): Boolean {
val view = rv.findChildViewUnder(event.x, event.y) //获取当前x\y坐标的itemView
rv.getChildAdapterPosition(view) //通过view来获取列表位置
return super.onInterceptTouchEvent(rv, event)
}
}
通过以上示例就可以操作获取到的view执行想要的效果实现需求了~