最近、会社のプロジェクトに取り組んでいるときに、スライディングの競合に遭遇しました。ページ構造は比較的複雑です。CoordinatorLayout + AppBarLayout + ViewPager + RecyclerView(1) + RecyclerView(2)。AppBarLayout を展開すると、ViewPager 領域がプッシュされる必要があります。 RecyclerView(1) はスライドする前に最初に上に移動しますが、RecyclerView(1) によってネストされている RecyclerView(2) 領域内をスライドする場合、AppBarLayout を上に押し出す操作はトリガーされず、AppBarLayout はまだ展開された状態のままです。具体的な状況は次のとおりです(表示される RecyclerView(2) は水平方向にスライドします)。
解決策は次のとおりです。
RecyclerView(2)
縦型の場合はsetNestedScrollingEnabled(false)
直接セットするだけです。
水平の場合はRecyclerView(2)
、次の 2 つの手順を実行する必要があります。
(1)設定RecyclerView(2).setNestedScrollingEnabled(false)
(2)RecyclerView(2)
外側のビューで垂直スライド イベントをインターセプトし、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;
}