È possibile disabilitare lo scorrimento su un ViewPager


138

Ho un ViewPagerche crea un'istanza a View. Vorrei disabilitare momentaneamente sia lo scorrimento del viewpager che i pulsanti figlio mentre un risultato di ricerca viene restituito alla vista. Ho chiamato viewPager.setEnabled(false)ma questo non lo disabilita.

Qualcuno ha qualche idea?


Risposte:


356

Una soluzione semplice è quella di creare la propria sottoclasse di ViewPagerche ha una private booleanbandiera isPagingEnabled. Quindi sovrascrivere i metodi onTouchEvente onInterceptTouchEvent. Se isPagingEnableduguale a vero invoca il supermetodo, altrimenti return.

public class CustomViewPager extends ViewPager {

    private boolean isPagingEnabled = true;

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

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

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

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

    public void setPagingEnabled(boolean b) {
        this.isPagingEnabled = b;
    }
}

Quindi nel tuo Layout.XMLfile sostituisci tutti i <com.android.support.V4.ViewPager>tag con <com.yourpackage.CustomViewPager>tag.

Questo codice è stato adattato da questo post sul blog .


2
soluzione greate, funziona bene. Se vuoi smettere di scorrere come una scimmia puoi sovrascrivere un OnPageChangeListener con @Override public void onPageScrollStateChanged (stato int finale) {switch (stato) {case ViewPager.SCROLL_STATE_SETTLING: mPager.setPagingEnabled (false); rompere; case ViewPager.SCROLL_STATE_IDLE: mPager.setPagingEnabled (true); rompere; } // noop}
Informatic0re

13
PS: in XML, usa <yourpkgname.CustomViewPager ... invece di <com.android, support.v4.ViewPager ...
thecr0w,

per aggiungere un'altra soluzione simile, puoi utilizzare la libreria chiamata "JazzyViewPager": github.com/jfeinstein10/JazzyViewPager e chiamare setPagingEnabled (booleano)
sviluppatore Android

è possibile interrompere lo scorrimento solo a destra? posso scorrere solo a sinistra
Saif Hamed il

È ancora possibile "scorrere" focalizzando gli elementi (pulsanti, ecc.) Nelle pagine quando si utilizza un controller di gioco o una tastiera, ad esempio. Come disabilitarlo completamente? Immagino sia un altro tipo di evento che dovrebbe essere intercettato ...
David Ferrand,

34

C'è una soluzione semplice per questo:

Quando si desidera disabilitare lo scorrimento del viewpager, allora:

mViewPager.setOnTouchListener(new OnTouchListener() {

   public boolean onTouch(View arg0, MotionEvent arg1) {
      return true;
   }
}); 

E quando vuoi riattivarlo, allora:

mViewPager.setOnTouchListener(null);

Quello farà il trucco.


46
Quasi, ma non del tutto. Il touchdown si verifica ancora, quindi puoi spostare le pagine eseguendo molti piccoli passaggi.
Flynny75,

@Akhil Sekharan Stava affrontando il problema esattamente quello che Flynny sta affrontando quando usa questa risposta .. ma per fortuna non so quanto all'improvviso quell'errore sia andato .. :) e ha funzionato come un fascino !!
Zombie,

Puoi fare un sacco di piccoli passaggi in modo che tu debba ancora superare il pubblico booleano onInterceptTouchEvent (evento MotionEvent) {cavalca secondo la risposta delle slatons
Ryan Heitner,

28

Ecco la mia leggera variante della risposta di Slayton:

public class DeactivatableViewPager extends ViewPager {
    public DeactivatableViewPager(Context context) {
        super(context);
    }

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

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return !isEnabled() || super.onTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return isEnabled() && super.onInterceptTouchEvent(event);
    }
}

Con il mio codice è possibile disabilitare il paging con setEnable().


La sostituzione onInterceptTouchEvent()impedirà alle visualizzazioni figlio di ricevere input. Nella maggior parte dei casi questo non è il comportamento previsto.
Alex Semeniuk,

19

Ho trovato una soluzione semplice.

//disable swiping
mViewPager.beginFakeDrag();

//enable swiping
mViewPager.endFakeDrag();

È tutto questo il codice che hai usato? Questo non funziona per me.
Jared Burrows,

17
Non funziona per me. Posso ancora fare un sacco di piccoli colpi.
DYS,

Questo codice non è corretto bcz Sta scorrendo molto lentamente come appeso vista
Ghanshyam Nayma

Questo potrebbe funzionare per fortuna. L'aggiornamento a ViewPager può interrompere questo hack.
Puntatore Null

Si sta ancora trascinando, ma a poco a poco (.
Ekashking,

14

Suggerisco un altro modo di risolvere questo problema. L'idea sta avvolgendo il tuo viewPager da uno scrollView, in modo che quando questo scrollView non è scorrevole, anche il tuo viewPager non è scorrevole.

Ecco il mio layout XML:

        <HorizontalScrollView
            android:id="@+id/horizontalScrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true" >

            <android.support.v4.view.ViewPager
                android:id="@+id/viewPager"
                android:layout_width="wrap_content"
                android:layout_height="match_parent" />

        </HorizontalScrollView>

Nessun codice necessario

Funziona bene per me.


1
Tra tutte queste risposte, penso che sia semplice e funzioni perfettamente !!
SREE,

OK ... MA quando hai una mappa come uno dei frammenti in ViewPager, allora ... è un problema
ekashking

4

Per disabilitare lo scorrimento

 mViewPager.beginFakeDrag();

Per abilitare lo scorrimento

 mViewPager.endFakeDrag();

2
Lo scorrimento è ancora possibile, non è più fluente. Fondamentalmente questo sta solo peggiorando la qualità senza risolvere il problema.
Benjamin Basmaci,

1
risposta duplicata
Ricardo A.

3

La migliore soluzione che ha funzionato per me è:

public class DeactivatedViewPager extends ViewPager {

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

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

    @Override
    public boolean canScrollHorizontally(int direction) {
        return false;
    }
}

Dopodiché lo scorrimento verrà disabilitato al tocco e quindi sarà comunque possibile utilizzare il setCurrentItemmetodo per cambiare pagina.


Non so perché, ma semplicemente non ha funzionato. Lo scorrimento avviene ancora.
Ricardo A.

1
Il canScrollHorizontally()metodo non ha alcun effetto nello scenario corrente. Non viene nemmeno chiamato quando si verifica lo scorrimento.
Alex Semeniuk,

3

Ecco una risposta in Kotlin e AndroidX

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.viewpager.widget.ViewPager

class DeactivatedViewPager @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : ViewPager(context, attrs) {

    var isPagingEnabled = true

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

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

2

Che ne dici di questo:
ho usato CustomViewPager
e poi, ignora lo scroll Per il metodo
ho controllato il movimento quando facevo molti piccoli passaggi, non scorre ad altre pagine.

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) {
            return super.onTouchEvent(event);
        }

        return false;
    }

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

        return false;
    }

    public void setPagingEnabled(boolean enabled) {
        this.enabled = enabled;
    } 

    @Override
    public void scrollTo(int x, int y) {
       if(enabled) {
          super.scrollTo(x, y);
       }
    }
}

Ho avuto il problema che il viewpager stava ancora facendo piccoli passaggi, ma l'override ha View.scrollTo(int x, int y)risolto questo problema per me. Grazie
Palm

Causa qualche comportamento strano in alcuni casi. Come andare nel vuoto e lasciare solo una pagina vuota '-'
Ricardo A.,

2

Nel mio caso di utilizzo di ViewPager 2 alpha 2, lo snippet di seguito funziona

viewPager.isUserInputEnabled = false

Possibilità di disabilitare l'input dell'utente (setUserInputEnabled, isUserInputEnabled)

fare riferimento a questo per ulteriori modifiche in viewpager2 1.0.0-alpha02

Inoltre sono state apportate alcune modifiche all'ultima versione ViewPager 2 alpha 4

Gli attributi orientamento e isUserScrollable non fanno più parte di SavedState

fare riferimento a questo per ulteriori modifiche in viewpager2 # 1.0.0-alpha04


1

La nuova classe ViewPager2 di androidx consente di disabilitare lo scorrimento con il metodo setUserInputEnabled (false)

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

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

0

La risposta di slayton funziona bene. Se vuoi smettere di scorrere come una scimmia puoi sovrascrivere un OnPageChangeListener con

@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; 
        } 
    }

Quindi puoi solo scorrere fianco a fianco


1
Non ho trovato alcun metodo di ViewPager come setPagingEnabled (valore booleano)
Rakesh Yadav

setPagingEnabled (valore booleano) deve essere creato dall'utente, poiché non esiste un metodo di questo tipo da sovrascrivere.
Kharak,

Non è chiaro cosa setPagingEnabled()faccia questo metodo. Si prega di includere il codice completo.
Alex Semeniuk,

0
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*/);
    }
}
}

Quindi nel tuo file Layout.XML sostituisci tutti i tag --- com.android.support.V4.ViewPager --- con i tag --- com.yourpackage.NonSwipeableViewPager ---.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.