Чи можна відключити прокрутку на ViewPager


138

У мене є ViewPagerінстанція View. Мені хотілося б на мить відключити прокручування вікна перегляду та дочірні кнопки, коли результат пошуку повернеться до перегляду. Я дзвоню, viewPager.setEnabled(false)але це не відключає.

Хтось мав якісь ідеї?


Відповіді:


355

Просте рішення , щоб створити свій власний підклас , ViewPagerякий має private booleanпрапор, isPagingEnabled. Потім переосмислити onTouchEventі onInterceptTouchEventметоди. Якщо isPagingEnabledдорівнює істина, виклик superметоду, в іншому випадку 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.XMLфайлі замініть будь-які <com.android.support.V4.ViewPager>теги <com.yourpackage.CustomViewPager>тегами.

Цей код було адаптовано з цієї публікації в блозі .


2
жирний розчин, прекрасно працює. Якщо ви хочете перестати розмовляти, як мавпа, ви можете замінити OnPageChangeListener з загальнодоступною пустотою @Override onPageScrollStateChanged (остаточний стан int) {switch (state) {case ViewPager.SCROLL_STATE_SETTLING: mPager.setPagingEnabled (false); перерва; case ViewPager.SCROLL_STATE_IDLE: mPager.setPagingEnabled (вірно); перерва; } // noop}
— Informatic0re

13
PS: У XML використовуйте <yourpkgname.CustomViewPager ... замість <com.android, support.v4.ViewPager ...
— thecr0w

щоб додати ще одне подібне рішення, ви можете використовувати бібліотеку під назвою "JazzyViewPager": github.com/jfeinstein10/JazzyViewPager , а також просто зателефонувати setPagingEnabled (boolean)
— андроїд розробник

чи можна припинити прокручування лише праворуч? я можу прокрутити лише ліворуч
— Сайф Хамед

Ще можна "прокручувати", фокусуючи елементи (кнопки тощо) на сторінках, наприклад, використовуючи ігровий контролер або клавіатуру. Як це повністю відключити? Я думаю, це ще один тип подій, який слід перехопити ...
— Девід Ферран

34

Для цього є легке виправлення:

Якщо ви хочете відключити прокрутку панелі перегляду:

mViewPager.setOnTouchListener(new OnTouchListener() {

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

А тоді, коли ви хочете знову ввімкнути це:

mViewPager.setOnTouchListener(null);

Це зробить трюк.


46
Майже, але не зовсім. Торкнення вниз все ж відбувається, тому ви можете переміщувати сторінки, роблячи безліч дрібних пальців.
— Flynny75

@Akhil Sekharan зіткнувся з проблемою саме з тим, з яким стикається Флінні, використовуючи цю відповідь .. але, на щастя, не знаю, як раптом ця помилка пішла .. :) і спрацювала як шарм !!
— Зомбі

Ви можете робити багато невеликих перебігів, так що вам все одно доведеться перевищувати загальнодоступну програму onInterceptTouchEvent (MotionEvent) {їздити відповідно до відповіді слотонів
— Ryan Heitner

28

Ось мій легкий варіант відповіді слайтона:

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

За допомогою мого коду ви можете відключити підключення сторінки setEnable().


Переоцінка onInterceptTouchEvent()перешкоджатиме переглядам дочірніх даних отримувати інформацію. У більшості випадків це не цілеспрямована поведінка.
— Олексій Семенюк

19

Я знайшов просте рішення.

//disable swiping
mViewPager.beginFakeDrag();

//enable swiping
mViewPager.endFakeDrag();

Це весь код, який ви використовували? Це не працює для мене.
— Джаред Берроуз

17
Не працює для мене. Ще можна зробити чимало пальців.
— DYS

Цей код не є належним bcz. Він прокручується дуже повільно, як висячий вид
— Ghanshyam Nayma

Це може спрацювати на удачу. Оновлення до ViewPager може зламати цей злом.
— Вказівник Null

Він все ще тягнеться, але потроху (.
— екшакінг

14

Я пропоную інший спосіб вирішити цю проблему. Ідея полягає в тому, щоб перетворити ваш viewPager на scrollView, так що коли цей scrollView не можна прокручувати, ваш viewPager також не можна прокручувати.

Ось мій 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>

Код не потрібен.

Добре працює для мене.


1
Серед усіх цих відповідей я вважаю, що це просто і працює чудово !!
— SREE

Гаразд ... АЛЕ коли у вас є карта як один із фрагментів у ViewPager, то ... це проблема
— ekashking

4

Щоб вимкнути функцію пальця

 mViewPager.beginFakeDrag();

Щоб увімкнути перехід пальцем

 mViewPager.endFakeDrag();

2
Прокрутка все ще можлива, її просто не вільно говорити. Це в основному просто погіршення якості без вирішення проблеми.
— Бенджамін Басмачі

1
дубльована відповідь
— Рікардо А.

3

Найкраще рішення, яке працювало для мене:

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

Після цього прокрутка буде відключена натисканням, і тоді ви все ще можете скористатися setCurrentItemметодом для зміни сторінки.


Не знаю чому, але це просто не вийшло. Прокрутка все ж відбувається.
— Рікардо А.

1
canScrollHorizontally()Метод не має ніякого ефекту в поточному сценарії. Його навіть не називають, коли відбудеться пальцем.
— Олексій Семенюк

3

Ось відповідь у Kotlin та 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

Як щодо цього:
я використав CustomViewPager
наступний, переосмислений прокрутку. Для способу
перевірки руху, коли роблю багато невеликих пальців, він не прокручується на інші сторінки.

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

У мене була проблема в тому, що оглядач все ще робив невеликі перегони, але View.scrollTo(int x, int y)вирішення цієї проблеми було вирішено для мене. Спасибі
— Palm

Це викликає в деяких випадках дивну поведінку. Як іти в порожнечу і залишати лише порожню сторінку '-'
— Рікардо А.

2

У моєму випадку використання ViewPager 2 alpha 2, наведений нижче фрагмент працює

viewPager.isUserInputEnabled = false

Можливість відключення введення користувача (setUserInputEnabled, isUserInputEnabled)

зверніться до цього для отримання додаткових змін у viewpager2 1.0.0-alpha02

Також були внесені деякі зміни останньої версії ViewPager 2 alpha 4

орієнтація та isUserScrollable атрибути більше не є частиною SavedState

зверніться до цього для отримання додаткових змін у viewpager2 # 1.0.0-alpha04


1

Новий клас ViewPager2 від androidx дозволяє відключити прокрутку методом setUserInputEnabled (false)

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

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

0

Відповідь слайтона працює чудово. Якщо ви хочете перестати мотатися, як мавпа, ви можете замінити 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; 
        } 
    }

Таким чином, ви можете лише пальцем побігати


1
Я не знайшов жодного методу ViewPager, такого як setPagingEnabled (булеве значення)
— Ракеш Ядав

setPagingEnabled (булеве значення) має бути створений вами, оскільки немає такого способу, який можна переосмислити.
— Харак

Незрозуміло, що setPagingEnabled()робить цей метод. Будь ласка, включіть повний код.
— Олексій Семенюк

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

Потім у файлі Layout.XML замініть будь-які теги --- com.android.support.V4.ViewPager --- тегами --- com.yourpackage.NonSwipeableViewPager ---.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.