Ist es möglich, das Scrollen auf einem ViewPager zu deaktivieren?

138

Ich habe eine, ViewPagerdie a instanziiert View. Ich möchte sowohl das Scrollen des Viewpagers als auch die untergeordneten Schaltflächen für einen Moment deaktivieren, während ein Suchergebnis zur Ansicht zurückgegeben wird. Ich habe angerufen, viewPager.setEnabled(false)aber das deaktiviert es nicht.

Hat jemand irgendwelche Ideen?

mAndroid
quelle

Antworten:

355

Eine einfache Lösung besteht darin, eine eigene Unterklasse zu erstellen ViewPager, die ein private booleanFlag hat isPagingEnabled. Überschreiben Sie dann die Methoden onTouchEventund onInterceptTouchEvent. Wenn isPagingEnabledgleich true, rufen Sie superandernfalls die Methode auf 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;
    }
}

Layout.XMLErsetzen Sie dann in Ihrer Datei alle <com.android.support.V4.ViewPager>Tags durch <com.yourpackage.CustomViewPager>Tags.

Dieser Code wurde aus diesem Blog-Beitrag angepasst .

Slayton
quelle
2
Lösung erstellen, funktioniert gut. Wenn Sie aufhören möchten, wie ein Affe zu wischen, können Sie einen OnPageChangeListener mit @Override public void onPageScrollStateChanged (endgültiger int-Status) {switch (state) {case ViewPager.SCROLL_STATE_SETTLING: mPager.setPagingEnabled (false) überschreiben. brechen; case ViewPager.SCROLL_STATE_IDLE: mPager.setPagingEnabled (true); brechen; } // noop}
Informatic0re
13
PS: Verwenden Sie in XML <yourpkgname.CustomViewPager ... anstelle von <com.android, support.v4.ViewPager ...
thecr0w
Um eine weitere ähnliche Lösung hinzuzufügen, können Sie die Bibliothek "JazzyViewPager" verwenden: github.com/jfeinstein10/JazzyViewPager , und einfach setPagingEnabled (boolean)
Android-Entwickler
Kann man den Bildlauf nur nach rechts beenden? Ich kann nur nach links scrollen
Saif Hamed
Es ist weiterhin möglich, durch Fokussieren von Elementen (Schaltflächen usw.) auf den Seiten zu "scrollen", wenn Sie beispielsweise einen Gamecontroller oder eine Tastatur verwenden. Wie kann man das komplett deaktivieren? Ich denke, es ist eine andere Art von Ereignis, das abgefangen werden sollte ...
David Ferrand
34

Es gibt eine einfache Lösung für dieses Problem:

Wenn Sie den Viewpager-Bildlauf deaktivieren möchten, gehen Sie wie folgt vor:

mViewPager.setOnTouchListener(new OnTouchListener() {

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

Und wenn Sie es dann wieder aktivieren möchten:

mViewPager.setOnTouchListener(null);

Das wird den Trick machen.

Akhil Sekharan
quelle
46
Fast, aber nicht ganz. Das Aufsetzen erfolgt weiterhin, sodass Sie Seiten verschieben können, indem Sie viele kleine Wischvorgänge ausführen.
Flynny75
@Akhil Sekharan stand vor dem Problem genau dem, was Flynny bei der Verwendung dieser Antwort gegenübersteht .. aber zum Glück weiß ich nicht, wie plötzlich dieser Fehler verschwunden ist .. :) und hat wie ein Zauber funktioniert !!
Zombie
Sie können die vielen kleinen Wischvorgänge ausführen, sodass Sie immer noch über den öffentlichen Booleschen Wert onInterceptTouchEvent (MotionEvent-Ereignis) {Fahrt gemäß Slatons-Antwort
Ryan Heitner
28

Hier ist meine leichte Variante von Slaytons Antwort:

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

Mit meinem Code können Sie das Paging mit deaktivieren setEnable().

rekire
quelle
Durch das Überschreiben onInterceptTouchEvent()wird verhindert, dass untergeordnete Ansichten Eingaben erhalten. In den meisten Fällen ist dies nicht das beabsichtigte Verhalten.
Alex Semeniuk
19

Ich habe eine einfache Lösung gefunden.

//disable swiping
mViewPager.beginFakeDrag();

//enable swiping
mViewPager.endFakeDrag();
Ja, ja
quelle
Ist das der gesamte Code, den Sie verwendet haben? Das funktioniert bei mir nicht.
Jared Burrows
17
Funktioniert bei mir nicht Kann immer noch viele kleine Wischbewegungen machen.
DYS
Dieser Code ist nicht richtig bcz Es rollt sehr langsam wie hängende Ansicht
Ghanshyam Nayma
Dies kann durch Glück funktionieren. Ein Update auf ViewPager kann diesen Hack unterbrechen.
Zeiger Null
Es zieht immer noch, aber nach und nach (.
Ekashking
14

Ich schlage einen anderen Weg vor, um dieses Problem zu lösen. Die Idee ist, Ihren viewPager mit einer scrollView zu versehen, sodass Ihr viewPager auch nicht scrollbar ist, wenn diese scrollView nicht scrollbar ist.

Hier ist mein XML-Layout:

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

Kein Code notwendig.

Funktioniert gut für mich.

M. Marmor
quelle
1
Unter all diesen Antworten finde ich, dass dies einfach ist und gut funktioniert !!
SREE
OK ... ABER wenn Sie eine Karte als eines der Fragmente in ViewPager haben, dann ... ist es ein Problem
ekashking
4

Swipe deaktivieren

 mViewPager.beginFakeDrag();

Swipe aktivieren

 mViewPager.endFakeDrag();
Isaias Carrera
quelle
2
Scrollen ist immer noch möglich, es ist einfach nicht mehr fließend. Dies verschlechtert im Grunde nur die Qualität, ohne das Problem zu lösen.
Benjamin Basmaci
1
doppelte Antwort
Ricardo A.
3

Die beste Lösung, die für mich funktioniert hat, ist:

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

Danach wird der Bildlauf durch Berühren deaktiviert und Sie können weiterhin die setCurrentItemMethode zum Wechseln der Seite verwenden.

Pradeep Kumar Kushwaha
quelle
Ich weiß nicht warum, aber es hat einfach nicht funktioniert. Das Scrollen geschieht immer noch.
Ricardo A.
1
Die canScrollHorizontally()Methode hat im aktuellen Szenario keine Auswirkung. Es wird nicht einmal aufgerufen, wenn ein Wischen stattfindet.
Alex Semeniuk
3

Hier ist eine Antwort in Kotlin und 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
quelle
2

Wie wäre es damit:
Ich habe CustomViewPager
die scrollTo-Methode verwendet und als nächstes überschrieben.
Ich habe die Bewegung überprüft, wenn ich viele kleine Wischvorgänge ausgeführt habe. Sie wird nicht zu anderen Seiten gescrollt.

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);
       }
    }
}
Auf Wiedersehen
quelle
Ich hatte das Problem, dass der Viewpager immer noch kleine Wischvorgänge ausführte, aber das Überschreiben View.scrollTo(int x, int y)löste dieses Problem für mich. Vielen Dank
Palm
In einigen Fällen verursacht es ein seltsames Verhalten. Als würde man ins Leere gehen und nur eine leere Seite hinterlassen - '
Ricardo A.
2

In meinem Fall mit ViewPager 2 alpha 2 funktioniert das folgende Snippet

viewPager.isUserInputEnabled = false

Möglichkeit zum Deaktivieren von Benutzereingaben (setUserInputEnabled, isUserInputEnabled)

Weitere Änderungen in viewpager2 1.0.0-alpha02 finden Sie hier

Außerdem wurden einige Änderungen an der neuesten Version von ViewPager 2 alpha 4 vorgenommen

Orientierungs- und isUserScrollable-Attribute sind nicht mehr Teil von SavedState

Weitere Änderungen in viewpager2 # 1.0.0-alpha04 finden Sie hier

Piyush Johnson
quelle
1

Die neue Klasse ViewPager2 von androidx ermöglicht das Deaktivieren des Bildlaufs mit der Methode setUserInputEnabled (false).

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

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

Die Antwort von Slayton funktioniert gut. Wenn Sie aufhören möchten, wie ein Affe zu wischen, können Sie einen OnPageChangeListener mit überschreiben

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

Sie können also nur nebeneinander wischen

Informatic0re
quelle
1
Ich habe keine ViewPager-Methode wie setPagingEnabled (boolescher Wert) gefunden
Rakesh Yadav
setPagingEnabled (boolescher Wert) muss von Ihnen erstellt werden, da es keine solche Methode gibt, die überschrieben werden kann.
Kharak
Unklar, was diese setPagingEnabled()Methode bewirkt. Bitte geben Sie den vollständigen Code an.
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*/);
    }
}
}

Ersetzen Sie dann in Ihrer Layout.XML-Datei alle --- com.android.support.V4.ViewPager --- -Tags durch --- com.yourpackage.NonSwipeableViewPager --- -Tags.

masoud jabbarian
quelle