Enregistrement des problèmes - conflits de glissement imbriqués et solutions

Récemment, lorsque je travaillais sur un projet d'entreprise, j'ai rencontré un conflit de glissement. La structure de la page est plus compliquée. CoordinatorLayout + AppBarLayout + ViewPager + RecyclerView(1) + RecyclerView(2). Lorsque AppBarLayout est développé, la zone ViewPager doit être poussée vers le haut de l'AppBarLayout avant de glisser RecyclerView(1), mais lors du glissement dans la zone RecyclerView(2) imbriquée par RecyclerView(1), cela ne déclenchera pas l'opération de poussée de l'AppBarLayout vers le haut, et l'AppBarLayout est toujours dans le état déplié, la situation spécifique est la suivante (le RecyclerView(2) affiché est un glissement horizontal) :

a9707038fdd44da88373d77f88da252f.gif

 

La solution est la suivante :

S'il RecyclerView(2)est vertical, setNestedScrollingEnabled(false)réglez-le directement.

S'il RecyclerView(2)est horizontal, vous devez effectuer deux étapes :

(1) réglageRecyclerView(2).setNestedScrollingEnabled(false)

(2) RecyclerView(2)Interceptez l'événement de glissement vertical dans la vue externe et réécrivez dispatchTouchEvent()方法le code spécifique comme suit :

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

 

 

Je suppose que tu aimes

Origine blog.csdn.net/qq_43679375/article/details/126270646
conseillé
Classement