ViewPager üzerinde kaydırmayı devre dışı bırakmak mümkün mü


138

Bir ViewPagerörneği var View. Bir arama sonucu görünüme döndürülürken, hem görüntüleyicinin hem de alt düğmelerin kaydırılmasını geçici olarak devre dışı bırakmak istiyorum. Ben arıyorum viewPager.setEnabled(false)ama bu devre dışı bırakmaz.

Kimsenin fikri yok mu?


Yanıtlar:


356

Basit bir çözüm, ViewPagerbir private booleanbayrağı olan kendi alt sınıfınızı oluşturmaktır isPagingEnabled. Sonra onTouchEventve onInterceptTouchEventyöntemlerini geçersiz kılın . Eğer isPagingEnabledçağırmak doğrudur eşittir super, aksi takdirde yöntemle 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;
    }
}

Ardından, Layout.XMLdosyanızdaki tüm <com.android.support.V4.ViewPager>etiketleri etiketlerle değiştirin <com.yourpackage.CustomViewPager>.

Bu kod, bu blog yayınından uyarlandı .


2
greate çözümü, iyi çalışıyor. Maymun gibi kaydırmayı durdurmak istiyorsanız, bir OnPageChangeListener'ı @Override public void ile geçersiz kılabilirsiniz onPageScrollStateChanged (final int state) {switch (state) {case ViewPager.SCROLL_STATE_SETTLING: mPager.setPagingEnabled (false); break; case ViewPager.SCROLL_STATE_IDLE: mPager.setPagingEnabled (true); break; } // noop}
Informatic0re

13
PS: XML'de, <com.android, support.v4.ViewPager ... yerine <yourpkgname.CustomViewPager ... kullanın.
thecr0w

başka bir benzer çözüm eklemek için, "JazzyViewPager" adlı kütüphaneyi kullanabilirsiniz: github.com/jfeinstein10/JazzyViewPager ve sadece setPagingEnabled (boolean)
android geliştirici

sadece sağa kaydırmayı durdurmak mümkün mü? Ben sadece sola kaydırma yapabilirsiniz
Saif Hamed

Örneğin bir oyun kumandası veya klavye kullanılırken sayfalardaki öğeleri (düğmeler vb.) Odaklayarak "kaydırmak" mümkündür. Bunu nasıl tamamen devre dışı bırakabilirim? Sanırım ele geçirilmesi gereken başka bir olay ...
David Ferrand

34

Bunun için kolay bir düzeltme var:

Viewpager kaydırmasını devre dışı bırakmak istediğinizde:

mViewPager.setOnTouchListener(new OnTouchListener() {

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

Ve yeniden etkinleştirmek istediğinizde:

mViewPager.setOnTouchListener(null);

Hile yapacak.


46
Neredeyse ama tam olarak değil. Aşağı dokunma yine de gerçekleşir, böylece çok sayıda küçük kaydırma yaparak sayfaları taşıyabilirsiniz.
Flynny75

@Akhil Sekharan Bu cevap kullanırken tam olarak Flynny'nin karşılaştığı sorunla karşı karşıya kaldım .. ama neyse ki bu hatanın nasıl gittiğini bilmiyorum .. :) ve bir cazibe gibi çalıştı!
Zombi

Hala kamu boolean onInterceptTouchEvent üzerinde (MotionEvent olayı) zorunda slatons cevap gereğince Sen {binmek küçük kaydırma hareketiyle çok yapabilirim
Ryan Heitner

28

İşte slayton cevabının hafif varyantı:

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

Kodumla ile sayfalamayı devre dışı bırakabilirsiniz setEnable().


Geçersiz kılma onInterceptTouchEvent(), alt görünümlerin girdi almasını engeller. Çoğu durumda bu amaçlanan davranış değildir .
Alex Semeniuk

19

Basit bir çözüm buldum.

//disable swiping
mViewPager.beginFakeDrag();

//enable swiping
mViewPager.endFakeDrag();

Kullandığınız kodun tamamı bu mu? Bu benim için çalışmıyor.
Jared Burrows

17
Benim için çalışmıyor. Yine de birçok küçük tokat yapabilir.
DYS

Bu kod uygun değil bcz Bu asma görünümü gibi çok yavaş
kaydırıyor

Bu şansla işe yarayabilir. ViewPager güncellemesi bu hack kırmak olabilir.
Pointer Null

Hala sürükleniyor ama
yavaş yavaş

14

Bu sorunu çözmenin başka bir yolunu öneririm. Fikir, viewPager öğenizi bir scrollView ile sarmaktır, böylece bu scrollView kaydırılamaz olduğunda, viewPager öğeniz de kaydırılamaz.

İşte benim XML düzeni:

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

Kod gerekmez.

Benim için iyi çalışıyor.


1
Tüm bu cevaplar arasında, bu basit ve iyi çalışıyor hissediyorum !!
SREE

Tamam ... ANCAK ViewPager içinde bir parça olarak bir harita olduğunda o zaman ... bu bir sorun
ekashking

4

Kaydırmayı devre dışı bırakmak için

 mViewPager.beginFakeDrag();

Kaydırmayı etkinleştirmek için

 mViewPager.endFakeDrag();

2
Kaydırma hala mümkün, artık akıcı değil. Bu temel olarak sorunu çözmeden kaliteyi kötüleştiriyor.
Benjamin Basmaci

1
yinelenen cevap
Ricardo A.

3

Benim için çalışan en iyi çözüm:

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

Bundan sonra kaydırma dokunarak devre dışı bırakılacak ve daha sonra setCurrentItemsayfayı değiştirmek için yöntemi kullanabilirsiniz .


Nedenini bilmiyorum, ama işe yaramadı. Kaydırma hala gerçekleşiyor.
Ricardo A.

1
canScrollHorizontally()Yöntem mevcut senaryoda hiçbir etkisi yoktur. Kaydırma olduğunda bile çağrılmaz.
Alex Semeniuk

3

İşte Kotlin ve androidX'te bir cevap

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

Buna ne dersiniz:
Kullandım CustomViewPager
ve sonra scroll'u geçersiz kılın Metod
Çok sayıda küçük kaydırma yaparken hareketi kontrol ettim, diğer sayfalara kaymaz.

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

Viewpager'ın hala küçük tokatlar yapması sorunu vardı, ancak geçersiz kılma View.scrollTo(int x, int y)bu sorunu benim için çözdü. Teşekkürler
Palm

Bazı durumlarda garip davranışlara neden olur. Boşluğa gitmek ve sadece boş bir sayfa bırakmak gibi '-'
Ricardo A.

2

ViewPager 2 alpha 2'yi kullanmam durumunda aşağıdaki snippet çalışıyor

viewPager.isUserInputEnabled = false

Kullanıcı girişini devre dışı bırakma özelliği (setUserInputEnabled, isUserInputEnabled)

viewpager2 1.0.0-alpha02'deki diğer değişiklikler için buna bakın

Ayrıca bazı değişiklikler yapıldı en son sürüm ViewPager 2 alpha 4

yönlendirme ve isUserScrollable öznitelikleri artık SavedState'in bir parçası değildir

viewpager2 # 1.0.0-alpha04'teki diğer değişiklikler için buna bakın


1

Androidx'ten yeni sınıf ViewPager2 yöntem setUserInputEnabled (false) ile kaydırmayı devre dışı bırakmanıza izin verir

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

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

0

Slayton cevabı iyi çalışıyor. Maymun gibi kaydırmayı durdurmak istiyorsanız, bir OnPageChangeListener'ı

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

Böylece sadece yan yana kaydırabilirsiniz


1
SetPagingEnabled (boolean değeri) gibi herhangi bir ViewPager yöntemi bulamadım
Rakesh Yadav

setPagingEnabled (boolean değeri) sizin tarafınızdan yaratılacaktır, çünkü geçersiz kılmak için böyle bir yöntem yoktur.
Kharak

Bu setPagingEnabled()yöntemin ne yaptığı net değil . Lütfen kodun tamamını ekleyin.
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*/);
    }
}
}

Ardından Layout.XML dosyanızda --- com.android.support.V4.ViewPager --- etiketlerini --- com.yourpackage.NonSwipeableViewPager --- etiketleriyle değiştirin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.