È 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.