最近在做公司项目时,遇到一种滑动冲突,页面结构比较复杂, CoordinatorLayout +AppBarLayout +ViewPager +RecyclerView(1) +RecyclerView(2) ,在AppBarLayout 展开时滑动ViewPager 区域应该先将AppBarLayout 顶上去再滑动RecyclerView(1) , 但是在RecyclerView(1) 嵌套的RecyclerView(2) 区域滑动时不会触发将AppBarLayout 顶上去的操作,AppBarLayout 还是展开状态,具体情况如下(展示的RecyclerView(2)为横向滑动的):
解决方法如下:
如果RecyclerView(2)
是纵向的,直接设置setNestedScrollingEnabled(false)
就行了。
如果RecyclerView(2)
是横向的,则需要做两步:
(1)设置RecyclerView(2).setNestedScrollingEnabled(false)
(2)在RecyclerView(2)
外层View对纵向滑动事件进行拦截,重写dispatchTouchEvent()方法
具体代码如下:
/**横纵方向上的偏移*/
private float mOffsetX,mOffsetY;
/**上次落点的横纵坐标*/
private float mLastPosX,mLastPosY;
/**与边缘线的间距阈值*/
private int mInterval;
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean result = true;
switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
mOffsetX = 0;
mOffsetY = 0;
mLastPosX = ev.getX();
mLastPosY = ev.getY();
result = super.dispatchTouchEvent(ev);
break;
default:
float thisPosX = ev.getX();
float thisPosY = ev.getY();
mOffsetX += Math.abs(thisPosX - mLastPosX);//x轴偏差
mOffsetY += Math.abs(thisPosY - mLastPosY);//y轴偏差
mLastPosX = thisPosX;
mLastPosY = thisPosY;
if (mOffsetX < mInterval && mOffsetY < mInterval){
//false表示传给子控件,此时为点击事件
result = super.dispatchTouchEvent(ev);
}else if (mOffsetX < mOffsetY){
//true表示不传给子控件,此时为垂直滚动
result = false;
}else{
//false表示传给子控件,此时为水平滚动
result = super.dispatchTouchEvent(ev);
}
break;
}
return result;
}