ViewPager'de parmağınızla hızlıca kaydırarak sayfalamayı nasıl devre dışı bırakabilirsiniz ancak yine de programlı olarak hızlıca kaydırabilirsiniz?


550

ViewPager var ve altında 10 düğme var. Örneğin # 4 düğmesine tıklandığında, çağrı cihazı hemen 4 numaralı sayfaya gider mPager.setCurrentItem(3);. Ancak, parmağınızı yatay olarak kaydırarak sayfalamayı devre dışı bırakmak istiyorum. Böylece, sayfalama SADECE düğmelere tıklanarak yapılır . Peki, parmakla kaydırmayı nasıl devre dışı bırakabilirim?


ViewFlipper'ı ilk etapta kullanmaya ne dersiniz ? Size büyük bir baş ağrısından kurtaracaktır.
Alex Semeniuk

Yanıtlar:


885

Alt sınıfa ihtiyacınız var ViewPager. onTouchEventçocuk görüşlerinin dokunmalarına izin vermek gibi değiştirmek istemediğiniz birçok iyi şey var. onInterceptTouchEventdeğiştirmek istediğiniz şeydir. Koduna bakarsanız ViewPager, yorumu görürsünüz:

    /*
     * This method JUST determines whether we want to intercept the motion.
     * If we return true, onMotionEvent will be called and we do the actual
     * scrolling there.
     */

İşte tam bir çözüm:

İlk olarak, bu sınıfı srcklasörünüze ekleyin :

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

    public NonSwipeableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        setMyScroller();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages
        return false;
    }

    //down one is added for smooth scrolling

    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, ViewPagermuhtemelen belirttiğiniz normal yerine bu sınıfı kullandığınızdan emin olun android.support.v4.view.ViewPager. Düzen dosyanızda, aşağıdakine benzer bir şeyle belirtmek istersiniz:

<com.yourcompany.NonSwipeableViewPager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" />

Bu özel örnek LinearLayouta'dadır ve tüm ekranı kaplamak içindir, bu yüzden layout_weight1 velayout_height a'dadır kaplamak içindir 0dp'dir.

Ve setMyScroller();yöntem düzgün geçiş için


3
@louielouie Bir yan notta: Tam ekran efekti elde etmek için 0dpyükseklik / 1ağırlık çözümünü neden yüksekliğe göre seçtiniz match_parent? Bunu yaparak performans geliştirmeleri elde ediyor musunuz?
Ubuntudroid

29
Bu cevap, klavye sol / sağ tuşlarını kullanırken sayfanın kaydırılmasını engellemez (öykünücüde deneyin). Dokunmatik cihazlar için bir sorun olmayabilir, ancak TV ve dizüstü bilgisayarlarda bir sorun olabilir.
Vincent Mimoun-Prat

8
@MarvinLabs @Thorbear Sayfa kaydırmayı klavyeyle devre dışı bırakmanın doğru yolu geçersiz kılmaktır executeKeyEvent(). Bu çağrılan yöntemdir allowScroll(). // Never allow swiping by keyboard LEFT, RIGHT, TAB and SHIFT+TAB keys @Override public boolean executeKeyEvent(KeyEvent event) { return false; }
araks

6
Bu, dikey kaydırmayı da devre dışı bırakır ... liste görünümleri kullanıyorsanız bu kötüdür.
maysi

5
Umarım sadece incitmediğine inandığım için dokunma / kaydırmayı nasıl ele alacağımızla ilgili arayüz yöntemimizi sağladığımız bir yöntem olabilir mi?
Neon Warge

466

Daha genel uzantısı , anında sayfalamayı etkinleştirip devre dışı bırakabilmemiz ViewPageriçin bir SetPagingEnabledyöntem oluşturmak olacaktır . Kaydırmayı etkinleştirmek / devre dışı bırakmak için sadece iki yöntemi geçersiz kılın: onTouchEventve onInterceptTouchEvent. Disk belleği devre dışı bırakılmışsa her ikisi de "false" değerini döndürür.

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

Ardından, XML'deki yerleşik görüntüleyici yerine bunu seçin

<mypackage.CustomViewPager 
    android:id="@+id/myViewPager" 
    android:layout_height="match_parent" 
    android:layout_width="match_parent" />

Sadece setPagingEnabledyöntemi ile çağırmanız yeterlidir falseve kullanıcılar sayfa numaralandırmak için hızlıca kaydıramaz.


3
Yatay kaydırma kullanılan (örneğin, AChartEngine grafiği) birkaç alt görünüme sahip bir görünüm için mükemmel çalışır. Parçamda, kullanıcının grafiğe (ACTION_MOVE) dokunmasına veya bırakmasına (ACTION_CANCEL) bağlı olarak çağrıyı kapatmasını veya kapatmasını söyleyen etkinliğim için bir geri arama kullanıyorum. Çok teşekkürler!
riper

32
onTouchEventVe onInterceptTouchEventyöntemlerinizi basitleştirebilirsinizreturn enabled && super.onTouchEvent(event);
nbarraille

2
@nbarraille bu sadece bir stil meselesi. Sizin için daha okunabilir görünen herhangi bir stili kullanabilirsiniz.
Rajul

7
Ayrıca alan adının "etkin" den "swipePageChangeEnabled" veya bunun gibi bir şey değiştirilmesini tavsiye ederim. Kodu yazdıktan bir ay sonra, özellikle sınıfınıza "CustomViewPager" adı verildiğinde, "özelleştirme" nin ne anlama geldiğini hatırlayamazsınız. Bu aynı zamanda bir stil meselesidir, ancak desteklenmeyen bir proje ile sonuçlanmak istemiyorsanız, stil önemlidir, bu tamamen yeniden yazmaktan daha kolay.
bytefu

4
SetPagingEnabled'ı nereden ararım? ._.
Ntikki

107

En basit yolu olduğunu setOnTouchListenerve karşılığında trueiçin ViewPager.

mPager.setOnTouchListener(new OnTouchListener()
    {           
        @Override
        public boolean onTouch(View v, MotionEvent event)
        {
            return true;
        }
    });

53
Bazen çalışmıyor. Bir FragmentPagerAdapter ve birkaç Fragment ile bir ViewPager kullanıyorum. OnTouchListener'ı çağrı cihazına ayarladıktan sonra, sola atarsam UI biraz sola hareket eder.
Chris.Zou

16
Dönmeden pager.setCurrentItem(pager.getCurrentItem());önce eklediğinizde çalışır true.
dng

1
daha önce benim için çalıştı. neden artık iyi çalışmadığını bilmiyorum.
android geliştirici

Benim için iş gibi görünüyor. public int getItemPosition(Object object) { return POSITION_NONE; }Bağdaştırıcımda bulunan ve sayfaların yeniden oluşturulmasını zorlayan ve belki de diğer sorunları çözen bazı düzen hatalarını çözmek için .
r-hold

6
Bu kısmen çalışan bir çözümdür. Yatay kaydırmalar garip bir şekilde ele alınır. Bunu bir ViewPager'in bir parçası olarak bir Drag'n Drop Gridview ile test ettim. Bu çözümü kullanarak sürüklerken soldan sağa ve sağdan sola sürükleme başarısız olur. Şahsen Rajul'un yaklaşımını en iyi buluyorum.
Ton Snoei

58

Stilize etmek daha iyi, böylece özelliğini xml'den değiştirebilirsiniz:

private boolean swipeable;

public MyViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyViewPager);
    try {
        swipeable = a.getBoolean(R.styleable.MyViewPager_swipeable, true);
    } finally {
        a.recycle();
    }
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    return swipeable ? super.onInterceptTouchEvent(event) : false;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    return swipeable ? super.onTouchEvent(event) : false;
}

Ve değerlerinizde / attr.xml:

<declare-styleable name="MyViewPager">
  <attr name="swipeable" format="boolean" />
</declare-styleable>

böylece düzen xml'de kullanabilirsiniz:

<mypackage.MyViewPager
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/viewPager"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:swipeable="false" />

Tabii ki, hala bir get / set özelliğine sahip olabilirsiniz.


58

Yalnızca geçersiz kılma onTouchEventveonInterceptTouchEvent başka bir ViewPager içinde ViewPager olması durumunda yeterli değildir. Child ViewPager, ilk / son sayfasında konumlandırılmadığı sürece üst ViewPager öğesinden yatay kaydırma dokunma olaylarını çalacaktır.

Bu kurulumun düzgün çalışması için canScrollHorizontallyyöntemi de geçersiz kılmanız gerekir .

Aşağıdaki LockableViewPageruygulamaya bakınız.

public class LockableViewPager extends ViewPager {

    private boolean swipeLocked;

    public LockableViewPager(Context context) {
        super(context);
    }

    public LockableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public boolean getSwipeLocked() {
        return swipeLocked;
    }

    public void setSwipeLocked(boolean swipeLocked) {
        this.swipeLocked = swipeLocked;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return !swipeLocked && super.onTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return !swipeLocked && super.onInterceptTouchEvent(event);
    }

    @Override
    public boolean canScrollHorizontally(int direction) {
        return !swipeLocked && super.canScrollHorizontally(direction);
    }

}

3
Teşekkür ederim, bu başka bir ViewPager içindeki bir ViewPager üzerinde çok iyi çalışıyor.
Fernanda Bari

1
Bu benim için, başka bir ViewPager içindeki bir ViewPager için de işe yarar. Bu durumda doğru çözüm benim için işe yaramadı.
Rafael Ruiz Muñoz

sekmelerde kullanıldığında animasyonu da durdurur.
Rishabh Srivastava

Eğer devre dışı bırakırsam ve etkinleştirmek istediğimi varsayarsam, o zaman olayı setSwipeLocked (false) çağırmak için nereden alabilirim?
Ravi Yadav

57

Artık özel oluşturmaya gerek yok ViewPager

ViewPager2 Android'de mevcut yeni bir ad görüntüle

Dikey yönlendirme desteği

  • ViewPager2geleneksel yatay sayfalamaya ek olarak dikey sayfalamayı destekler. Bir ViewPager2öğe için android:orientationözelliğini ayarlayarak dikey sayfalamayı etkinleştirebilirsiniz

XML kullanma

<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:orientation="vertical" />

Kod kullanma

viewpager2Kullanımdaki kaydırmayı devre dışı bırakmak için

viewPager2.setUserInputEnabled(false);

viewpager2Kullanımda kaydırmayı etkinleştirmek için

viewPager2.setUserInputEnabled(true);

daha fazla bilgi için bunu kontrol edin

GÜNCELLEME


3
Harika, ama yine de eksik görünüyor. Ben 5 farklı parçaları ile denedim ve sayfalar arasında geçiş sonra parçaları bir tür kayboldu, yani görünüm ne geri ne de yeniden şişirilmiş değildi
Toochka

@Toochka, benim için iyi çalıştığını duyduğuma üzüldüm, buradan örnek çalışma kodunu bulabilirsiniz. Stackoverflow.com/a/54643817/7666442 mümkünse lütfen kodunuzu paylaşın
Nilesh Rathod

1
Bu yöntemi kullanarak bir ViewPager2 üzerinde kaydırmayı başarıyla devre dışı bırakabilirim
voghDev

1
duyduğuma @voghDev mutlu
Nilesh Rathod

1
@PhaniRithvij Bu cevap kontrol ediniz stackoverflow.com/a/54643817/7666442 i nasıl kullanmak tüm ayrıntıları eklediniz viewpager2ileRecyclerView.Adapter
Nilesh Rathod

35

ViewPager'den genişliyorsanız, daha önce @araks ile gösterildiği gibi geçersizexecuteKeyEvent kılmalısınız

@Override
public boolean executeKeyEvent(KeyEvent event)
{
    return isPagingEnabled ? super.executeKeyEvent(event) : false;
}

Çünkü Galaxy Tab 4 10 'gibi bazı cihazlar, çoğu cihazın asla göstermediği yerlerde bu düğmeleri gösterir:

Klavye tuşları


50
Samsung, Android geliştiricileri için her zaman işleri mahvediyor.
toobsco42

2
@ toobsco42 Samsung bu durumda yalnız değil. SwiftKey (popüler klavye uygulaması), kullanıcıların klavyelerine ok koymasına izin verir.
Sufian

1
Bu, bir klavye / izci topunu kullanan birinin çağrı cihazınızı sayfalandırmasını durdurmak istiyorsanız da düzeltmedir.
se22as

28

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

mViewPager.beginFakeDrag();

Kaydırmayı etkinleştirmek için

mViewPager.endFakeDrag();

22
İyi bir çözüm değil, çünkü en azından uygulamamda küçük hareket bölümlerine izin veriyor.
Koras

Benim için iyi çalışıyor. Sunulan diğer çözümlere kıyasla dezavantajları nelerdir?
userM1433372

13

Belirli bir sayfada kaydırmayı devre dışı bırakmam ve güzel bir lastik bant animasyonu vermem gerekiyordu, şöyle:

    mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageScrolled(int position, float positionOffset,
                                   int positionOffsetPixels) {
            if (position == MANDATORY_PAGE_LOCATION && positionOffset > 0.5) {
                mViewPager.setCurrentItem(MANDATORY_PAGE_LOCATION, true);
            }
        }

Bir sonraki sayfa kısmen görünene kadar bekler. Sonraki sayfa için bir kod onPageSelectedyürütülür. Bir sonraki sayfa bile değişecektir. Bu nedenle, bu kod gerekli değildir.
CoolMind

13

Bunu göndermek için çok geç olduğunu biliyorum ama sonuçlarınıza ulaşmak için küçük bir kesmek;)

Görüntüleyicinizin altına sahte bir görünüm eklemeniz yeterlidir:

<android.support.v4.view.ViewPager
     android:layout_width="match_parent"
     android:layout_height="match_parent">
</android.support.v4.view.ViewPager>

<RelativeLayout
     android:id="@+id/dummyView"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
</RelativeLayout>

Ardından, öğenize a OnClickListenerekleyin RelativeLayout.

dummyView = (RelativeLayout) findViewById(R.id.dummyView);

dummyView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
         //Just leave this empty
    }
});

Düzenler, yerleşimleri ve davranışlarıyla biraz yaratıcı olun ve hayal ettiğiniz her şeyi yapmanın bir yolunu bulmayı öğreneceksiniz :)

İyi şanslar!


Etkinliği işlemeniz gerekmiyorsa, setClickablebunun yerine daha kolay bir yol kullanılır . setOnClickListeneronClick
Kaos

bu ayrıca görüntüleyicideki dokunuşları engellemez mi?
android geliştirici

Evet olacak. OP @androiddeveloper tarafından beklenen beklenen davranıştır
Dinuka Jay

@RickGrimesTheCoder Sorumumu anladığınızı sanmıyorum. Demek istediğim, görüntüleyicinin fragmanlarındaki görüntüler. Hala dokunabilir olacaklar mı?
android geliştirici

Hayır, görüntüleyicinin kendisi bir tıklama dinleyicisine sahip olduğu için olmayacak. Bu yalnızca parçalar içinde etkileşimli öğelerin bulunmadığı durumlar için uygundur. Örneğin, parçalarını dinamik olarak değiştiren bir Hoş Geldiniz ViewPager @androiddeveloper
Dinuka Jay

12

CustomViewPagerBir kaydırma kontrolü ile bir yazdım :

public class ScrollableViewPager extends ViewPager {
    private boolean canScroll = true;
    public ScrollableViewPager(Context context) {
        super(context);
    }
    public ScrollableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public void setCanScroll(boolean canScroll) {
        this.canScroll = canScroll;
    }
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return canScroll && super.onTouchEvent(ev);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return canScroll && super.onInterceptTouchEvent(ev);
    }
}

Eğer ayarlarsanız canScrolliçin true, bu ViewPager, parmağıyla kaydırarak edilebilir falsetersine.

Bunu projemde kullanıyorum ve şimdiye kadar harika çalışıyor.


1
ViewPager içinde bir düğme varsa ve tıklama istiyorum ne olur? Bu çözüm tıklanabilir viewpager altındaki her şeyi durdurur ..
aimiliano

6

Bu sınıfı başarıyla kullandım. Bazı aygıtlarda oklar kullanarak veya erişilebilirlik sağlamak için executeKeyEvent'in geçersiz kılınması gerekir:

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;

public class ViewPagerNoSwipe extends ViewPager {
    /**
     * Is swipe enabled
     */
    private boolean enabled;

    public ViewPagerNoSwipe(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.enabled = false; // By default swiping is disabled
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return this.enabled ? super.onTouchEvent(event) : false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return this.enabled ? super.onInterceptTouchEvent(event) : false;
    }

    @Override
    public boolean executeKeyEvent(KeyEvent event) {
        return this.enabled ? super.executeKeyEvent(event) : false;
    }

    public void setSwipeEnabled(boolean enabled) {
        this.enabled = enabled;
    }

}

Ve xml'de şöyle deyin:

<package.path.ViewPagerNoSwipe
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

İşe yarıyor. Yalnızca hızlıca kaydırma devre dışı bırakılır ve bir sekmeye tıklamak etkinleştirilir. AS, bu performClick()yöntemin geçersiz kılınmadığı konusunda uyarır .
CoolMind

5

Kotlin'de benim çözümüm, yukarıdaki cevapları birleştirerek.

class CustomViewPager(context: Context, attrs: AttributeSet): ViewPager(context, attrs) {
    var swipeEnabled = false

    override fun onTouchEvent(ev: MotionEvent?): Boolean {
        return if (swipeEnabled) super.onTouchEvent(ev) else false
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        return if (swipeEnabled) super.onInterceptTouchEvent(ev) else false
    }

    override fun executeKeyEvent(event: KeyEvent): Boolean {
        return if (swipeEnabled) super.executeKeyEvent(event) else false
    }
}

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

Her parçanın çocuk görüşleri ile etkileşime geçtim. Ne kastettiğinizden emin değilim.
Jeff Padgett

5

Kotlin'de, ViewPager sınıfını devralan özel bir widget oluşturarak ve kaydırma davranışını kontrol etmek için bir bayrak değeri ekleyerek bunu çözebiliriz.

NoSwipePager.kt

class NoSwipePager(context: Context, attrs: AttributeSet) : ViewPager(context, attrs) {

    var pagingEnabled: Boolean = false

    override fun onTouchEvent(event: MotionEvent): Boolean {
        return if (this.pagingEnabled) {
            super.onTouchEvent(event)
        } else false
    }

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        return if (this.pagingEnabled) {
            super.onInterceptTouchEvent(event)
        } else false
    }
}

Xml biçiminde

<your.package.NoSwipePager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/tab_layout" />

Programlı olarak kaydırmayı devre dışı bırakın. Eğer kotlin-android-extensionseklenti uygulanır build.gradle hızlıca kaydırmak kodunun altında yazarak devre dışı olabilir.

view_pager.pagingEnabled = false

Aksi takdirde, aşağıdaki kodu kullanarak kaydırmayı devre dışı bırakabiliriz:

val viewPager : ViewPager = findViewById(R.id.view_pager)
viewPager.pagingEnabled = false

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

@AlexSemeniuk Bunu uyguladıktan sonra herhangi bir sorun gözlemlediniz mi? Bazı işlemler için geri dönüşüm görüntüleme öğeleri üzerinde kaydırmayı etkinleştirmiştim ve iyi çalışıyor. Yani benim durumumda uygulama iyi çalışıyor.
Sagar Chapagain

Sagar Chapagain: ya da tabii ki yaptım. Sayfalarımın her biri, dokunuşları çeşitli şekillerde (kaydırma, sürükleme, tek ve uzun dokunmalar dahil) işleyen özel görünüm içeriyor. super.onInterceptTouchEvent(event)Bu görünümlerde herhangi bir girdi ( onInterceptTouchEventyöntemin belgelenmiş amacı ) alınmayan sonuçların çağrılmaması .
Alex Semeniuk

Bu durumda, çocuk parçasını kullanmayı ve backstack'i korumayı tercih etmelisiniz.
Sagar Chapagain

Bu mevcut soru ile ne kadar ilgili? Parçalar bazı kapların ( Görünümler ) içine yerleştirilir ve kendi düzeninde Görünümler bulunur . ViewPager içinde hangi içeriğe sahip olduğum önemli değil, hala geçersiz kılma onInterceptTouchEvent()yönteminin (içerik) girdi almasını engellediği gerçeğiyle ilgileniyorum .
Alex Semeniuk


1

Belirli bir sayfada kaydırmayı devre dışı bırakmak için başka bir kolay çözüm (bu örnekte, sayfa 2):

int PAGE = 2;
viewPager.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
        if (viewPager.getCurrentItem() == PAGE) {
                viewPager.setCurrentItem(PAGE-1, false);
                viewPager.setCurrentItem(PAGE, false);
                return  true;
        }
        return false;
}

1
This worked for me

viewPager.setOnTouchListener(new View.OnTouchListener() {
                                         @Override
                                         public boolean onTouch(View v, MotionEvent event) {
                                             if (viewPager.getCurrentItem() == 0) {
                                                 viewPager.setCurrentItem(-1, false);
                                                 return true;
                                             }
                                             else if (viewPager.getCurrentItem() == 1) {
                                                 viewPager.setCurrentItem(1, false);
                                                 return true;
                                             }
                                             else if (viewPager.getCurrentItem() == 2) {
                                                 viewPager.setCurrentItem(2, false);
                                                 return true;
                                             }
                                             return true;
                                         }
                                     });

1

ImageViewS ve ile ViewPageryakınlaştırma ve kaydırma özelliğini destekleyen bir resim galerisi yazarsanız , burada açıklanan basit bir çözüme bakın: Phimpme Android'de (ve Github örneği - PhotoView ) Varsayılan ViewPager'i Genişleterek yakınlaştırılabilir bir ImageView uygulama . Bu çözüm ViewPagertek başına çalışmaz .

public class CustomViewPager extends ViewPager {
    public CustomViewPager(Context context) {
        super(context);
    }

    public CustomViewPager(Context context, AttributeSet attrs)
    {
        super(context,attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        try {
            return super.onInterceptTouchEvent(event);
        } catch (IllegalArgumentException e) {
            return false;
        }
    }
}

1

ViewPager2 kullanıyorsanız sadece kullanmanız gerekenler:

viewpager.setUserInputEnabled(false);

Gönderen docs :

Kullanıcı tarafından başlatılan kaydırmayı etkinleştirin veya devre dışı bırakın. Buna dokunmatik giriş (kaydırma ve fırlatma hareketleri) ve erişilebilirlik girişi dahildir. Klavye girişinin devre dışı bırakılması henüz desteklenmemektedir. Kullanıcı tarafından başlatılan kaydırma devre dışı bırakıldığında, programlı setCurrentItem'de hala çalışır. Varsayılan olarak, kullanıcı tarafından başlatılan kaydırma etkindir.

Teşekkürler: https://stackoverflow.com/a/61685871/9026710


0

Aynı şeyi Xamarin'de Android için uygulamak istiyorsanız, işte C # için bir çeviri

" ScrollEnabled " özniteliğini adlandırmayı seçtim . Çünkü iOS sadece aynı isimlendirmeyi kullanıyor. Yani, her iki platformda da eşit adlandırma vardır, geliştiriciler için daha kolay hale getirir.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Support.V4.View;
using Android.Util;

namespace YourNameSpace.ViewPackage {

    // Need to disable swiping for ViewPager, if user performs Pre DSA and the dsa is not completed yet
    // http://stackoverflow.com/questions/9650265/how-do-disable-paging-by-swiping-with-finger-in-viewpager-but-still-be-able-to-s
    public class CustomViewPager: ViewPager {
        public bool ScrollEnabled;

        public CustomViewPager(Context context, IAttributeSet attrs) : base(context, attrs) {
            this.ScrollEnabled = true;
        }

        public override bool OnTouchEvent(MotionEvent e) {
            if (this.ScrollEnabled) {
                return base.OnTouchEvent(e);
            }
            return false;
        }

        public override bool OnInterceptTouchEvent(MotionEvent e) {
            if (this.ScrollEnabled) {
                return base.OnInterceptTouchEvent(e);
            }
            return false;
        }

        // For ViewPager inside another ViewPager
        public override bool CanScrollHorizontally(int direction) {
            return this.ScrollEnabled && base.CanScrollHorizontally(direction);
        }

        // Some devices like the Galaxy Tab 4 10' show swipe buttons where most devices never show them
        // So, you could still swipe through the ViewPager with your keyboard keys
        public override bool ExecuteKeyEvent(KeyEvent evt) {
            return this.ScrollEnabled ? base.ExecuteKeyEvent(evt) : false;
        }
    }
}

.Axml dosyasında:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  <YourNameSpace.ViewPackage.CustomViewPager
      android:id="@+id/pager"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@android:color/white"
      android:layout_alignParentTop="true" />
</LinearLayout>

0

Yukarıdaki kodlardan hiçbiri düzgün çalışmıyor. Bunu denedim

<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/pager"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent" />
                </HorizontalScrollView>

0

İşte benim uygulamasıdır
hala tokatlamak size swipeListener sol kullanabilirsiniz animasyon ve hakkını devre dışı bırakmak istediğiniz ve eğer parmak tarafından değil animasyon olmadan kaydırma istiyorum

1-Geçersiz kılma Viewpageryöntemi onInterceptTouchEventveonTouchEvent

2- kendinizinkini yaratın GestureDetector

3- kaydırma hareketini algılar ve setCurrentItem(item, false)

ViewPager

public class ViewPagerNoSwipe extends ViewPager {
    private final GestureDetector gestureDetector;
    private OnSwipeListener mOnSwipeListener;

    public void setOnSwipeListener(OnSwipeListener onSwipeListener) {
        mOnSwipeListener = onSwipeListener;
    }

    public ViewPagerNoSwipe(@NonNull Context context) {
        super(context);
        gestureDetector = new GestureDetector(context, new GestureListener());

    }

    public ViewPagerNoSwipe(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        gestureDetector = new GestureDetector(context, new GestureListener());


    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        gestureDetector.onTouchEvent(ev);
        return false;
    }

    public class GestureListener extends GestureDetector.SimpleOnGestureListener {

        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            boolean result = false;
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            if(mOnSwipeListener!=null)
                            mOnSwipeListener.onSwipeRight();
                        } else {
                            if(mOnSwipeListener!=null)
                                mOnSwipeListener.onSwipeLeft();
                        }
                        result = true;
                    }
                } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        if(mOnSwipeListener!=null)
                            mOnSwipeListener.onSwipeBottom();
                    } else {
                        if(mOnSwipeListener!=null)
                            mOnSwipeListener.onSwipeTop();
                    }
                    result = true;
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }

    public interface OnSwipeListener {

         void onSwipeRight();

        void onSwipeLeft();

        void onSwipeTop();

        void onSwipeBottom();
    }
}

ViewPager'i kurduğunuzda swipeListener'ı ayarlayın

postsPager.setOnSwipeListener(new ViewPagerNoSwipe.OnSwipeListener() {
            @Override
            public void onSwipeRight() {

              postsPager.setCurrentItem(postsPager.getCurrentItem() + 1,false);

            }

            @Override
            public void onSwipeLeft() {

            postsPager.setCurrentItem(postsPager.getCurrentItem() - 1, false);

            }
             ...
           }

0

Viewpager'ı biraz özelleştirdim ve kolayca kaydırmayı devre dışı bıraktım.

public class CustomViewPager extends ViewPager {

private boolean swipeLocked;

public CustomViewPager(Context context) {
    super(context);
}

public CustomViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public boolean getSwipeLocked() {
    return swipeLocked;
}

public void setSwipeLocked(boolean swipeLocked) {
    this.swipeLocked = swipeLocked;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    return !swipeLocked && super.onTouchEvent(event);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    return !swipeLocked && super.onInterceptTouchEvent(event);
}

@Override
public boolean canScrollHorizontally(int direction) {
    return !swipeLocked && super.canScrollHorizontally(direction);
}
}

-1
shareViewPager?.setOnTouchListener(object :View.OnTouchListener{
            override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                for (PAGE in 0..shareViewPager.adapter!!.count){
                    if (shareViewPager.currentItem==PAGE){
                        shareViewPager.setCurrentItem(PAGE-1,false)
                        shareViewPager.setCurrentItem(PAGE,false)
                    }}
                return true
            }

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