Czy można wyłączyć przewijanie w ViewPager?

138

Mam plik, ViewPagerktóry tworzy instancję View. Chciałbym na chwilę wyłączyć przewijanie podglądu i przycisków potomnych, podczas gdy wynik wyszukiwania jest zwracany do widoku. Dzwonię, viewPager.setEnabled(false)ale to go nie wyłącza.

Czy ktoś ma jakieś pomysły?

mAndroid
źródło

Odpowiedzi:

355

Prostym rozwiązaniem jest stworzenie własnej podklasy ViewPager, który ma private booleanflagę isPagingEnabled. Następnie zastąp metody onTouchEventi onInterceptTouchEvent. Jeśli isPagingEnabledrówna się true, wywołaj supermetodę, w przeciwnym razie 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;
    }
}

Następnie w Layout.XMLpliku zastąp wszystkie <com.android.support.V4.ViewPager>tagi <com.yourpackage.CustomViewPager>tagami.

Ten kod został dostosowany na podstawie tego posta na blogu .

Slayton
źródło
2
dobre rozwiązanie, działa dobrze. Jeśli chcesz przestać przesuwać jak małpa, możesz zastąpić OnPageChangeListener za pomocą @Override public void onPageScrollStateChanged (final int state) {switch (state) {case ViewPager.SCROLL_STATE_SETTLING: mPager.setPagingEnabled (false); przerwa; sprawa ViewPager.SCROLL_STATE_IDLE: mPager.setPagingEnabled (true); przerwa; } // noop}
Informatic0re
13
PS: W XML użyj <yourpkgname.CustomViewPager ... zamiast <com.android, support.v4.ViewPager ...
thecr0w
aby dodać inne podobne rozwiązanie, możesz użyć biblioteki o nazwie „JazzyViewPager”: github.com/jfeinstein10/JazzyViewPager i po prostu wywołać setPagingEnabled (boolean)
programista Androida
czy można zatrzymać przewijanie tylko w prawo? mogę przewijać tylko w lewo
Saif Hamed
Nadal możliwe jest „przewijanie” poprzez zaznaczanie elementów (przycisków itp.) Na stronach, na przykład podczas korzystania z kontrolera gier lub klawiatury. Jak to całkowicie wyłączyć? Myślę, że to inny rodzaj zdarzenia, które powinno być przechwycone ...
David Ferrand
34

Jest na to łatwe rozwiązanie:

Jeśli chcesz wyłączyć przewijanie podglądu, wtedy:

mViewPager.setOnTouchListener(new OnTouchListener() {

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

A jeśli chcesz go ponownie włączyć,:

mViewPager.setOnTouchListener(null);

To wystarczy.

Akhil Sekharan
źródło
46
Prawie, ale nie do końca. Przyziemienie nadal ma miejsce, więc możesz przenosić strony, wykonując wiele małych przesunięć.
Flynny75,
@Akhil Sekharan stanął przed problemem, z którym dokładnie boryka się Flynny, używając tej odpowiedzi .. ale na szczęście nie wiem, jak nagle ten błąd zniknął .. :) i działał jak urok !!
Zombie
Możesz wykonać wiele małych przesunięć, więc nadal musisz przesadzać z publicznymi wartościami logicznymi na InterceptTouchEvent (zdarzenie MotionEvent) {jazda zgodnie z odpowiedzią slatons
Ryan Heitner
28

Oto mój lekki wariant odpowiedzi Slaytona:

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

Za pomocą mojego kodu możesz wyłączyć stronicowanie za pomocą setEnable().

rekire
źródło
Zastępowanie onInterceptTouchEvent()uniemożliwi widokom podrzędnym otrzymywanie danych wejściowych. W większości przypadków nie jest to zamierzone zachowanie.
Alex Semeniuk,
19

Znalazłem proste rozwiązanie.

//disable swiping
mViewPager.beginFakeDrag();

//enable swiping
mViewPager.endFakeDrag();
Tak
źródło
Czy to cały kod, którego użyłeś? To nie działa dla mnie.
Jared Burrows,
17
Nie działa na mnie. Nadal można zrobić wiele małych przeciągnięć.
DYS
Ten kod nie jest poprawny bcz Przewija się bardzo wolno jak widok wiszący
Ghanshyam Nayma
To może zadziałać przez szczęście. Aktualizacja do ViewPager może złamać ten hack.
Wskaźnik zerowy
Wciąż się przeciąga, ale stopniowo (.
ekashking
14

Proponuję inny sposób rozwiązania tego problemu. Pomysł polega na zawijaniu twojego viewPagera przez scrollView, tak że gdy ten scrollView nie jest przewijalny, twój viewPager też nie jest przewijalny.

Oto mój układ 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>

Nie potrzeba żadnego kodu.

U mnie działa dobrze.

M. Marmor
źródło
1
Wśród wszystkich tych odpowiedzi wydaje mi się, że jest to proste i działa dobrze !!
SREE
OK ... ALE jeśli masz mapę jako jeden z fragmentów w ViewPager to ... to jest problem
ekashking
4

Aby wyłączyć przesuwanie

 mViewPager.beginFakeDrag();

Aby włączyć przesuwanie

 mViewPager.endFakeDrag();
Isaias Carrera
źródło
2
Przewijanie jest nadal możliwe, po prostu nie jest już płynne. To po prostu pogorszenie jakości bez rozwiązania problemu.
Benjamin Basmaci,
1
zduplikowana odpowiedź
Ricardo A.
3

Najlepsze rozwiązanie, które u mnie zadziałało to:

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

Po tym przewijanie zostanie wyłączone dotykiem i nadal możesz użyć setCurrentItemmetody zmiany strony.

Pradeep Kumar Kushwaha
źródło
Nie wiem dlaczego, ale to po prostu nie zadziałało. Przewijanie nadal się dzieje.
Ricardo A.
1
canScrollHorizontally()Metoda nie działa w obecnej sytuacji. Nie jest nawet wywoływane, gdy dzieje się przesunięcie.
Alex Semeniuk,
3

Oto odpowiedź w Kotlin i 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)
    }
}
Pasi Matalamäki
źródło
2

A co powiesz na to:
użyłem, CustomViewPager
a następnie override scrollTo metody
Sprawdziłem ruch podczas wykonywania wielu małych przesunięć, nie przewija się do innych stron.

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);
       }
    }
}
dowidzenia
źródło
Miałem problem z tym, że przeglądarka wciąż robiła małe przeciągnięcia, ale zastąpienie View.scrollTo(int x, int y)rozwiązało ten problem za mnie. Dzięki
Palm
W niektórych przypadkach powoduje to dziwne zachowanie. Jak pójście w pustkę i pozostawienie pustej strony '-'
Ricardo A.
2

W moim przypadku używania ViewPager 2 alpha 2 poniższy fragment kodu działa

viewPager.isUserInputEnabled = false

Możliwość wyłączenia wprowadzania danych przez użytkownika (setUserInputEnabled, isUserInputEnabled)

zajrzyj do tego po więcej zmian w viewpager2 1.0.0-alpha02

Wprowadzono również pewne zmiany w najnowszej wersji ViewPager 2 alfa 4

Orientacja i atrybuty isUserScrollable nie są już częścią SavedState

zajrzyj do tego po więcej zmian w viewpager2 # 1.0.0-alpha04

Piyush Johnson
źródło
1

Nowa klasa ViewPager2 z androidx pozwala wyłączyć przewijanie metodą setUserInputEnabled (false)

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

override fun onCreate(savedInstanceState: Bundle?) {
    pager.isUserInputEnabled = false
}
shushper
źródło
0

Odpowiedź Slaytona działa dobrze. Jeśli chcesz przestać przesuwać jak małpa, możesz zastąpić OnPageChangeListener za pomocą

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

Możesz więc przesuwać tylko obok siebie

Informatic0re
źródło
1
Nie znalazłem żadnej metody ViewPager, takiej jak setPagingEnabled (wartość logiczna)
Rakesh Yadav
setPagingEnabled (wartość logiczna) ma zostać utworzona przez Ciebie, ponieważ nie ma takiej metody do przesłonięcia.
Kharak
Nie jest jasne, co setPagingEnabled()robi ta metoda. Prosimy o dołączenie całego kodu.
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*/);
    }
}
}

Następnie w pliku Layout.XML zamień wszystkie tagi --- com.android.support.V4.ViewPager --- na tagi --- com.yourpackage.NonSwipeableViewPager ---.

masoud jabbarian
źródło