Apakah mungkin untuk menonaktifkan pengguliran pada ViewPager

138

Saya punya ViewPagerinstantiates a View. Saya ingin menonaktifkan penggulir viewpager dan tombol anak untuk sementara waktu sementara hasil pencarian dikembalikan ke tampilan. Saya sudah menelepon viewPager.setEnabled(false)tetapi ini tidak menonaktifkannya.

Ada yang punya ide?

mAndroid
sumber

Jawaban:

355

Solusi sederhana adalah membuat subclass Anda sendiri ViewPageryang memiliki private booleanflag isPagingEnabled,. Kemudian timpa metode onTouchEventdan onInterceptTouchEvent. Jika isPagingEnabledsama dengan benar memanggil supermetode, jika tidak 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;
    }
}

Kemudian di Layout.XMLfile Anda ganti semua <com.android.support.V4.ViewPager>tag dengan <com.yourpackage.CustomViewPager>tag.

Kode ini diadaptasi dari posting blog ini .

Slayton
sumber
2
solusi greate, bekerja dengan baik. Jika Anda ingin berhenti menggesekkan seperti monyet, Anda dapat menimpa OnPageChangeListener dengan @Override public void onPageScrollStateChanged (keadaan akhir) {switch (state) {case ViewPager.SCROLL_STATE_SETTLING: mPager.setPagingEnabled (false); istirahat; case ViewPager.SCROLL_STATE_IDLE: mPager.setPagingEnabled (true); istirahat; } // noop}
Informatic0re
13
PS: Dalam XML, gunakan <yourpkgname.CustomViewPager ... alih-alih <com.android, support.v4.ViewPager ...
thecr0w
untuk menambahkan solusi serupa lainnya, Anda dapat menggunakan perpustakaan yang disebut "JazzyViewPager": github.com/jfeinstein10/JazzyViewPager , dan cukup panggil setPagingEnabled (boolean)
pengembang android
apakah mungkin untuk berhenti menggulirkan saja? saya hanya bisa menggulir ke kiri
Saif Hamed
Dimungkinkan untuk "menggulir" dengan memfokuskan elemen (tombol, dll.) Di halaman saat menggunakan pengontrol permainan atau keyboard misalnya. Bagaimana cara menonaktifkannya sepenuhnya? Saya kira itu jenis acara lain yang harus dicegat ...
David Ferrand
34

Ada perbaikan yang mudah untuk ini:

Ketika Anda ingin menonaktifkan scroll viewpager maka:

mViewPager.setOnTouchListener(new OnTouchListener() {

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

Dan ketika Anda ingin mengaktifkannya kembali maka:

mViewPager.setOnTouchListener(null);

Itu akan melakukan triknya.

Akhil Sekharan
sumber
46
Hampir, tetapi tidak cukup. Sentuhan ke bawah masih terjadi, sehingga Anda dapat memindahkan halaman dengan melakukan banyak gesekan kecil.
Flynny75
@Akhil Sekharan Menghadapi masalah persis apa yang Flynny hadapi ketika menggunakan jawaban ini .. tapi untungnya tidak tahu bagaimana tiba-tiba kesalahan itu hilang .. :) dan bekerja seperti pesona !!
Zombie
Anda dapat melakukan banyak gesekan kecil sehingga Anda masih harus menggunakan boolean publik diInterceptTouchEvent (acara MotionEvent) {ride sesuai jawaban slatons
Ryan Heitner
28

Inilah varian ringan dari jawaban slayton saya:

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

Dengan kode saya, Anda dapat menonaktifkan paging dengan setEnable().

hidup kembali
sumber
Mengesampingkan onInterceptTouchEvent()akan mencegah pandangan anak untuk menerima input. Dalam kebanyakan kasus ini bukan perilaku yang dimaksudkan.
Alex Semeniuk
19

Saya menemukan solusi sederhana.

//disable swiping
mViewPager.beginFakeDrag();

//enable swiping
mViewPager.endFakeDrag();
Yessy
sumber
Apakah ini semua kode yang Anda gunakan? Ini tidak bekerja untuk saya.
Jared Burrows
17
Tidak bekerja untuk saya. Masih bisa melakukan banyak gesekan kecil.
DYS
Kode ini tidak tepat bcz.
Menggulirnya
Ini mungkin berhasil karena keberuntungan. Perbarui ke ViewPager dapat merusak hack ini.
Pointer Null
Ini masih menyeret tetapi sedikit demi sedikit (.
ekashking
14

Saya menyarankan cara lain untuk mengatasi masalah ini. Idenya adalah membungkus viewPager Anda dengan scrollView, sehingga ketika scrollView ini tidak dapat digulir, viewPager Anda juga tidak dapat digulir.

Berikut ini adalah tata letak XML saya:

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

Tidak diperlukan kode.

Bekerja dengan baik untuk saya.

M. Marmor
sumber
1
Di antara semua jawaban ini, saya merasa ini sederhana dan berfungsi dengan baik !!
SREE
OK ... TAPI ketika Anda memiliki peta sebagai salah satu fragmen di ViewPager maka ... itu masalah
ekashking
4

Untuk menonaktifkan geser

 mViewPager.beginFakeDrag();

Untuk mengaktifkan gesek

 mViewPager.endFakeDrag();
Isaias Carrera
sumber
2
Pengguliran masih dimungkinkan, tidak lancar lagi. Ini pada dasarnya hanya memperburuk kualitas tanpa menyelesaikan masalah.
Benjamin Basmaci
1
duplikat jawaban
Ricardo A.
3

Solusi terbaik yang bekerja untuk saya adalah:

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

Setelah ini gulir akan dinonaktifkan dengan sentuhan dan kemudian Anda masih dapat menggunakan setCurrentItemmetode untuk mengubah halaman.

Pradeep Kumar Kushwaha
sumber
Tidak tahu mengapa, tetapi itu tidak berhasil. Pengguliran masih terjadi.
Ricardo A.
1
The canScrollHorizontally()Metode tidak berpengaruh dalam skenario saat ini. Bahkan tidak dipanggil ketika swipe terjadi.
Alex Semeniuk
3

Inilah jawaban di Kotlin dan 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
sumber
2

Bagaimana dengan ini:
Saya menggunakan CustomViewPager
dan selanjutnya, menimpa scrollUntuk
saya memeriksa gerakan ketika melakukan banyak gesekan kecil, itu tidak gulir ke halaman lain.

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);
       }
    }
}
Tuhan
sumber
Saya memiliki masalah yang viewpager masih melakukan gesekan kecil, tetapi View.scrollTo(int x, int y)mengatasi memecahkan masalah ini untuk saya. Terima kasih
Palm
Itu menyebabkan beberapa perilaku aneh dalam beberapa kasus. Seperti pergi ke kekosongan dan hanya menyisakan halaman kosong '-'
Ricardo A.
2

Dalam kasus saya menggunakan ViewPager 2 alpha 2, potongan di bawah ini berfungsi

viewPager.isUserInputEnabled = false

Kemampuan untuk menonaktifkan input pengguna (setUserInputEnabled, isUserInputEnabled)

lihat ini untuk lebih banyak perubahan dalam viewpager2 1.0.0-alpha02

Juga beberapa perubahan dibuat versi terbaru ViewPager 2 alpha 4

atribut orientasi dan isUserScrollable tidak lagi menjadi bagian dari SavedState

lihat ini untuk lebih banyak perubahan dalam viewpager2 # 1.0.0-alpha04

Piyush Johnson
sumber
1

ViewPager2 kelas baru dari androidx memungkinkan untuk menonaktifkan pengguliran dengan metode setUserInputEnabled (false)

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

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

Jawaban slayton bekerja dengan baik. Jika Anda ingin berhenti menggesekkan seperti monyet, Anda bisa mengganti OnPageChangeListener dengan

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

Jadi Anda hanya bisa menggesek berdampingan

Informatic0re
sumber
1
Saya tidak menemukan metode apa pun dari ViewPager seperti setPagingEnabled (nilai boolean)
Rakesh Yadav
setPagingEnabled (nilai boolean) harus dibuat oleh Anda, karena tidak ada metode untuk ditimpa.
Kharak
Tidak jelas apa setPagingEnabled()yang dilakukan metode ini. Harap sertakan kode lengkap.
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*/);
    }
}
}

Kemudian di file Layout.XML Anda ganti tag --- com.android.sup.V4.ViewPager --- dengan tag --- com.yourpackage.NonSwipeableViewPager ---.

masoud jabbarian
sumber