155 votes

Est-il possible de désactiver le défilement sur un ViewPager ?

J'ai un ViewPager qui instancie un View . J'aimerais désactiver momentanément le défilement du viewpager et des boutons enfant pendant qu'un résultat de recherche est renvoyé à la vue. J'ai appelé viewPager.setEnabled(false) mais cela ne le désactive pas.

Quelqu'un a une idée ?

2voto

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.Scroller;
import java.lang.reflect.Field;

public class NonSwipeableViewPager extends ViewPager {

public NonSwipeableViewPager(Context context) {
    super(context);
}

public NonSwipeableViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    // stop swipe 
    return false;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    // stop switching pages
    return false;
}

private void setMyScroller() {
    try {
        Class<?> viewpager = ViewPager.class;
        Field scroller = viewpager.getDeclaredField("mScroller");
        scroller.setAccessible(true);
        scroller.set(this, new MyScroller(getContext()));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public class MyScroller extends Scroller {
    public MyScroller(Context context) {
        super(context, new DecelerateInterpolator());
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int 
duration) {
        super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/);
    }
}
}

Ensuite, dans votre fichier Layout.XML, remplacez toutes les balises --- com.Android.support.V4.ViewPager --- par des balises --- com.yourpackage.NonSwipeableViewPager ---.

Même solution mais en Kotlin :

class NonSwipeableViewPager constructor(
    context: Context,
    attrs: AttributeSet?
) : ViewPager(context, attrs) {

    private var isPagingEnabled = true

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        return isPagingEnabled && super.onTouchEvent(event)
    }

    override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
        return isPagingEnabled && super.onInterceptTouchEvent(event)
    }

    fun setPagingEnabled(isEnabled: Boolean) {
        isPagingEnabled = isEnabled
    }
}

2voto

Matt Smith Points 522

J'ai créé une version Kotlin basée sur la conversion de cette réponse depuis Java : https://stackoverflow.com/a/13437997/8023278

Il n'existe pas de moyen intégré pour désactiver le glissement entre les pages d'un ViewPager. Ce qu'il faut, c'est une extension de ViewPager qui surcharge onTouchEvent et onInterceptTouchEvent pour empêcher l'action de glissement. Pour rendre l'opération plus générale, nous pouvons ajouter une méthode setSwipePagingEnabled pour activer/désactiver le balayage entre les pages.

class SwipeLockableViewPager(context: Context, attrs: AttributeSet): ViewPager(context, attrs) {
    private var swipeEnabled = false

    override fun onTouchEvent(event: MotionEvent): Boolean {
        return when (swipeEnabled) {
            true -> super.onTouchEvent(event)
            false -> false
        }
    }

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        return when (swipeEnabled) {
            true -> super.onInterceptTouchEvent(event)
            false -> false
        }
    }

    fun setSwipePagingEnabled(swipeEnabled: Boolean) {
        this.swipeEnabled = swipeEnabled
    }
}

Ensuite, dans notre fichier xml de présentation, nous utilisons notre nouveau SwipeLockableViewPager au lieu du ViewPager standard.

<mypackage.SwipeLockableViewPager 
        android:id="@+id/myViewPager" 
        android:layout_height="match_parent" 
        android:layout_width="match_parent" />

Maintenant, dans notre activité/fragment, nous pouvons appeler myViewPager.setSwipePagingEnabled(false) et les utilisateurs ne pourront pas passer d'une page à l'autre.


UPDATE

En 2020, nous avons maintenant ViewPager2 . Si vous migrer à ViewPager2 il y a une méthode intégrée pour désactiver le swiping : myViewPager2.isUserInputEnabled = false

1voto

shushper Points 21

La nouvelle classe ViewPager2 d'androidx permet de désactiver le défilement avec la méthode setUserInputEnabled(false)

private val pager: ViewPager2 by bindView(R.id.pager)

override fun onCreate(savedInstanceState: Bundle?) {
    pager.isUserInputEnabled = false
}

0voto

Informatic0re Points 1705

La réponse de Slayton fonctionne bien. Si vous voulez arrêter de balayer comme un singe, vous pouvez remplacer un OnPageChangeListener avec

@Override public void onPageScrollStateChanged(final int state) { 
        switch (state) { 
            case ViewPager.SCROLL_STATE_SETTLING: 
                mPager.setPagingEnabled(false); 
                break; 
            case ViewPager.SCROLL_STATE_IDLE: 
                mPager.setPagingEnabled(true); 
                break; 
        } 
    }

Donc vous pouvez seulement glisser côte à côte

1 votes

Je n'ai trouvé aucune méthode de ViewPager telle que setPagingEnabled(boolean value).

0 votes

SetPagingEnabled(boolean value) est à créer par vous, car il n'y a pas de méthode à surcharger.

0 votes

On ne sait pas exactement ce que cela setPagingEnabled() méthode le fait. Veuillez inclure le code complet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X