ViewPager与RecyclerView的滑动冲突问题
ViewPager和RecyclerView控件是Android中非常高频使用的控件了,很多APP的主页都是使用ViewPager+Fragment来完成的
最近在项目中需要禁止RecyclerView控件的横向滑动引起的ViewPager页面切换
如图网易考拉海购也是这种需求, 主页是ViewPager滑动切换子Child Fragment,
Chlld Fragment内部有一个横向的RecyclerView控件, 如果对原生控件不做任何处理, 那么RecyclerView滑动到最后一个item时, 继续滑动将会引起外层的ViewPager的滑动, 即切换child Fragment了.
现在需求是对这个RecyclerView特殊处理, 让它滑动至最后一个item时, 继续向左滑动不会触发外层的ViewPager的滑动.
这里就需要对View的事件分发机制有一定的认识了,当我们点击屏幕时,就产生了点击事件,这个事件被封装成了一个对象,即MotionEvent, 当这个MotionEvent产生后, 系统会将这个对象传递给View的层级, 传递过程就是View的事件分发.这里有三个核心的回调方法:
- dispatchTouchEvent(MotionEvent ev): 顾名思义, 用来分发触摸事件
- onInterceptTouchEvent(MotionEvent ev): 用来进行事件的拦截, ViewGroup独有, 在dispatchTouchEvent()中调用
- onTouchEvent(MotionEvent ev): 用来处理点击事件
我们的需求是拦截掉ViewPager的滑动, 思路就清晰了.首先RecyclerView的滑动事件分发由RecyclerView的dispatchTouchEvent进行分发, 只需要重写此方法即可
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// interceptTouch是自定义属性控制是否拦截事件
if (interceptTouch){
ViewParent parent =this;
// 循环查找ViewPager, 请求ViewPager不拦截触摸事件
while(!((parent = parent.getParent()) instanceof ViewPager)){
// nop
}
parent.requestDisallowInterceptTouchEvent(true);
}
return super.dispatchTouchEvent(ev);
}
网友评论