Чи можна відключити прокрутку на 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.