Registro de problemas: conflictos deslizantes anidados y soluciones

Recientemente, cuando trabajaba en un proyecto de la empresa, me encontré con un conflicto deslizante. La estructura de la página es relativamente complicada. CoordinatorLayout + AppBarLayout + ViewPager + RecyclerView(1) + RecyclerView(2). Cuando se expande AppBarLayout, el área ViewPager debe empujarse hacia la parte superior de AppBarLayout antes de deslizar RecyclerView(1), pero cuando se desliza en el área de RecyclerView(2) anidada por RecyclerView(1), no activará la operación de empujar AppBarLayout hacia arriba, y AppBarLayout todavía está en el estado desplegado La situación específica es la siguiente (el RecyclerView (2) que se muestra es un deslizamiento horizontal):

a9707038fdd44da88373d77f88da252f.gif

 

La solución es la siguiente:

Si RecyclerView(2)es vertical, setNestedScrollingEnabled(false)simplemente configúrelo directamente.

Si RecyclerView(2)es horizontal, debe hacer dos pasos:

(1) configuraciónRecyclerView(2).setNestedScrollingEnabled(false)

(2) RecyclerView(2)Intercepte el evento de deslizamiento vertical en la Vista exterior y reescriba dispatchTouchEvent()方法el código específico de la siguiente manera:

    /**横纵方向上的偏移*/
    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;
    }

 

 

Supongo que te gusta

Origin blog.csdn.net/qq_43679375/article/details/126270646
Recomendado
Clasificación