web-dev-qa-db-fra.com

ViewPager désactiver le balayage dans une certaine direction

Je souhaite désactiver le balayage, mais uniquement sur le côté droit. J'ai trouvé une solution de travail dans this answer. Malheureusement, cela copie toute la source ViewPager pour atteindre l'objectif. Existe-t-il des méthodes héritant simplement de la classe existante et ne faisant pas double emploi?

18
WonderCsabo

Je ne suis pas sûr que c'est exactement ce dont vous avez besoin: j'avais besoin d'un viewpager pour un assistant avec une page max que l'utilisateur ne peut pas lui transmettre.

À la fin, la solution était dans l'adaptateur. J'ai changé le nombre de PagerAdapter et de cette façon empêche l'utilisateur de passer la page max:

@Override
public int getCount() {
    return mProgress; //max page + 1
}

Lorsque l'utilisateur passe à la page suivante:

private void setWizardProgress(int progress) {
    if(progress > mProgress) {
        mProgress = progress;
        mWizardPagerAdapter.notifyDataSetChanged();
    }
}

De cette façon, lorsque l'utilisateur est à la page maximale, il ne peut pas faire défiler vers la droite.

22
Aviv Mor

Voici la classe ViewPager qui fonctionne avec la possibilité de désactiver toute pagination de direction. Découvrez tous les réponse ici .

public class CustomViewPager extends ViewPager {
    private float initialXValue;
    private SwipeDirection direction;

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.direction = SwipeDirection.all;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (this.IsSwipeAllowed(event)) {
            return super.onTouchEvent(event);
        }

        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (this.IsSwipeAllowed(event)) {
            return super.onInterceptTouchEvent(event);
        }

        return false;
    }

    private boolean IsSwipeAllowed(MotionEvent event) {
        if(this.direction == SwipeDirection.all) return true;

        if(direction == SwipeDirection.none )//disable any swipe
            return false;

        if(event.getAction()==MotionEvent.ACTION_DOWN) {
            initialXValue = event.getX();
            return true;
        }

        if(event.getAction()==MotionEvent.ACTION_MOVE) {
            try {
                float diffX = event.getX() - initialXValue;
                if (diffX > 0 && direction == SwipeDirection.right ) {
                    // swipe from left to right detected
                    return false;
                }else if (diffX < 0 && direction == SwipeDirection.left ) {
                    // swipe from right to left detected
                    return false;
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }

        return true;
    }

    public void setAllowedSwipeDirection(SwipeDirection direction) {
        this.direction = direction;
    }
19
andre719mv

Un autre moyen simple consiste à utiliser setCurrentItem () pour revenir à la diapositive souhaitée si vous atteignez une certaine position. Par exemple, cela ne permettra que de glisser vers l'avant:

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

    @Override
    public void onPageSelected(int position) {
        if(position < mProgress) {
            mViewPager.setCurrentItem(mProgress, true);
        } else {
            mProgress = position;
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {}
});

Ou si vous voulez avoir une diapositive max:

if(position > 4) {
    mViewPager.setCurrentItem(4, true);
}

Techniquement, cette solution ne désactivera pas complètement le balayage, car vous verrez toujours une petite partie de la diapositive non autorisée lorsque vous effectuez votre mouvement de balayage. Mais pour certaines applications, cela peut être préféré.

8
jwBurnside

Vous pouvez essayer de suivre:

Étape 1: Créez une nouvelle classe personnalisée, dites "CustomViewPager". La classe hérite de "ViewPager" et inclut une nouvelle méthode personnalisée appelée "setPagingEnabled" dans le but d'activer/désactiver le balayage, en fonction des besoins.

Step2: Remplacez deux méthodes: "onTouchEvent" et "onInterceptTouchEvent". Les deux renverront "false" si la pagination doit être complètement désactivée.

Étape 3: Remplacez la balise "ViewPager" du fichier de mise en page par une classe personnalisée:

    <package_name.customviewpager 
     Android:id="@+id/customViewPager" 
     Android:layout_height="match_parent" 
     Android:layout_width="match_parent" />

Étape 4: CustomViewPager.Java

    public class CustomViewPager extends ViewPager {

private boolean enabled;

public CustomViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.enabled = true;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (this.enabled && detectSwipeToRight(event)) {
        return super.onTouchEvent(event);
    }

    return false;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (this.enabled && detectSwipeToRight(event)) {
        return super.onInterceptTouchEvent(event);
    }

    return false;
}

// To enable/disable swipe 
public void setPagingEnabled(boolean enabled) {
    this.enabled = enabled;
}

// Detects the direction of swipe. Right or left. 
// Returns true if swipe is in right direction
public boolean detectSwipeToRight(MotionEvent event){

 int initialXValue = 0; // as we have to detect swipe to right
 final int SWIPE_THRESHOLD = 100; // detect swipe
 boolean result = false;

        try {                
            float diffX = event.getX() - initialXValue;

                if (Math.abs(diffX) > SWIPE_THRESHOLD ) {
                    if (diffX > 0) {
                        // swipe from left to right detected ie.SwipeRight
                        result = false;
                    } else {
                        // swipe from right to left detected ie.SwipeLeft
                        result = true;
                    }
                }
            } 
         catch (Exception exception) {
            exception.printStackTrace();
        }
        return result;
    }
}
5
Ritesh Gune
private float initialXValue;
@Override
public boolean onTouchEvent(MotionEvent event) {
    if (this.mEnabled) {
        return super.onTouchEvent(event);
    }
    if(event.getAction()==MotionEvent.ACTION_DOWN){
        initialXValue = event.getX();
    }else if(event.getAction()==MotionEvent.ACTION_MOVE){
        if(detectSwipeToRight(event)){
            System.out.println("right swipe detected");
        }
    }
    return true;
}

private boolean detectSwipeToRight(MotionEvent event) {
    final int SWIPE_THRESHOLD = 100; // detect swipe
    boolean result = false;

    try {
        float diffX = event.getX() - initialXValue;
        if (Math.abs(diffX) > SWIPE_THRESHOLD) {
            if (diffX < 0) {
                // swipe from right to left detected ie.SwipeLeft
                result = true;
            }
        }
    } catch (Exception exception) {
        exception.printStackTrace();
    }
    return result;
}
1
Deepanshu

Vous pouvez utiliser les méthodes beginFakeDrag() et endFakeDrag().

beginFakeDrag() lorsque vous souhaitez désactiver le balayage et endFakeDrag() si vous souhaitez réactiver.

Comme ceci: viewPager.beginFakeDrag();

1
Ferran Ribell