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?


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 .


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.


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().


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

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.


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

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.


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

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

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


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
}

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


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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.