问题记录——嵌套滑动冲突和解决办法

最近在做公司项目时,遇到一种滑动冲突,页面结构比较复杂, CoordinatorLayout +AppBarLayout +ViewPager +RecyclerView(1) +RecyclerView(2) ,在AppBarLayout 展开时滑动ViewPager 区域应该先将AppBarLayout 顶上去再滑动RecyclerView(1) , 但是在RecyclerView(1) 嵌套的RecyclerView(2) 区域滑动时不会触发将AppBarLayout 顶上去的操作,AppBarLayout 还是展开状态,具体情况如下(展示的RecyclerView(2)为横向滑动的):

a9707038fdd44da88373d77f88da252f.gif

解决方法如下:

如果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;
    }

猜你喜欢

转载自blog.csdn.net/qq_43679375/article/details/126270646