У меня есть ViewPager, и ниже у меня есть 10 кнопок. Нажав на кнопку, например # 4, пейджер сразу же отправится на страницу # 4 на mPager.setCurrentItem(3);. Но я хочу отключить пейджинг, проводя пальцем по горизонтали. Таким образом, пейджинг выполняется  ТОЛЬКО, нажимая на кнопки.
Итак, как я могу отключить прокрутку пальцем?
Как отключить подкачку, прокручивая пальцем в ViewPager, но все же сможете прокручивать программно?
Ответ 1
 Вам нужно ViewPager подкласс ViewPager. onTouchEvent есть много хороших вещей, которые вы не хотите менять, например, позволяете дочерним видам касаться друг друга. onInterceptTouchEvent - это то, что вы хотите изменить. Если вы посмотрите на код для ViewPager, вы увидите комментарий:
    /*
     * 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.
     */
Здесь полное решение:
 Сначала добавьте этот класс в вашу папку src:
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*/);
        }
    }
}
 Затем убедитесь, что вы используете этот класс вместо обычного ViewPager, который вы, вероятно, указали как android.support.v4.view.ViewPager. В вашем файле макета вы захотите указать что-то вроде:
<com.yourcompany.NonSwipeableViewPager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" />
 Этот конкретный пример находится в LinearLayout и предназначен для LinearLayout всего экрана, поэтому layout_weight равен 1, а layout_height равен 0dp.
 И  setMyScroller(); метод для плавного перехода
Ответ 2
Более общим расширением ViewPager было бы создание метода SetPagingEnabled, чтобы мы могли включать и отключать пейджинг "на лету".
Чтобы включить/отключить прокрутку, просто переопределите два метода: onTouchEvent и onInterceptTouchEvent. Оба будут возвращать "false", если пейджинг был отключен.
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;
    } 
}
Затем выберите это вместо встроенного viewpager в XML
<mypackage.CustomViewPager 
    android:id="@+id/myViewPager" 
    android:layout_height="match_parent" 
    android:layout_width="match_parent" />
Вам просто нужно вызвать метод SetPagingEnabled с помощью false, и пользователи не смогут прокручивать страницы.
Ответ 3
Самый простой способ - setOnTouchListener и вернуть true для ViewPager.
mPager.setOnTouchListener(new OnTouchListener()
    {           
        @Override
        public boolean onTouch(View v, MotionEvent event)
        {
            return true;
        }
    });
Ответ 4
Лучше объявить его стильным, поэтому вы можете изменить его свойство из xml:
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;
}
И в ваших значениях /attr.xml:
<declare-styleable name="MyViewPager">
  <attr name="swipeable" format="boolean" />
</declare-styleable>
чтобы вы могли использовать его в своем макете xml:
<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" />
Конечно, вы все равно можете получить свойство get/set.
Ответ 5
Переопределить только onTouchEvent и onInterceptTouchEvent недостаточно, если у вас есть ViewPager непосредственно внутри другого ViewPager. Child ViewPager будет красть горизонтальные события касания прокрутки от родительского ViewPager, если он не расположен на первой/последней странице.
Чтобы эта настройка работала правильно, вам необходимо переопределить также метод canScrollHorizontally.
Ниже приведена реализация LockableViewPager.
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);
    }
}
Ответ 6
Чтобы отключить прокрутку
mViewPager.beginFakeDrag();
Чтобы включить прокрутку
mViewPager.endFakeDrag();
Ответ 7
Если вы расширяетесь от ViewPager, , вы также должны переопределить executeKeyEvent, как указано ранее, @araks
@Override
public boolean executeKeyEvent(KeyEvent event)
{
    return isPagingEnabled ? super.executeKeyEvent(event) : false;
}
Поскольку некоторые устройства, такие как Galaxy Tab 4 10 ', показывают эти кнопки, где большинство устройств никогда не показывают их:
Ответ 8
Мне нужно было отключить прокрутку на одной конкретной странице и дать ей приятную анимацию с резиновой лентой, вот как:
    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);
            }
        }
Ответ 9
Я написал CustomViewPager с помощью элемента управления:
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);
    }
}
Если вы установите canScroll на true, этот ViewPager может прокручиваться пальцем, false напротив.
Я использую это в своем проекте, и он отлично работает до сих пор.
Ответ 10
Я знаю, что очень поздно опубликовать это, но здесь крошечный взломать для достижения вашего результата;)
Просто добавьте фиктивный вид ниже вашего viewpager:
<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>
Затем добавьте OnClickListener к вашему RelativeLayout.
dummyView = (RelativeLayout) findViewById(R.id.dummyView);
dummyView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
         //Just leave this empty
    }
});
Получите немного объявлений с макетами, их местами размещения и их поведением, и вы научитесь находить способ сделать абсолютно все, что вы себе представляете:)
Удачи!
Ответ 11
Попробуйте переопределить и вернуть true из onInterceptTouchEvent() и/или onTouchEvent(), который будет потреблять события касания на пейджере.
Ответ 12
Я использовал этот класс с успехом. Переопределение executeKeyEvent требуется, чтобы избежать считывания с использованием стрелок на некоторых устройствах или для доступности:
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;
    }
}
И в XML это называется так:
<package.path.ViewPagerNoSwipe
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
Ответ 13
 Теперь нам не нужно создавать собственные ViewPager
 Новое имя   ViewPager2 View доступно в Android
 Чтобы отключить считывание в viewpager2 используйте
viewPager2.setUserInputEnabled(false);
 Чтобы включить viewpager2 в viewpager2 Используйте
viewPager2.setUserInputEnabled(true);
для получения дополнительной информации проверьте это
Ответ 14
В Kotlin моё решение, сочетающее приведенные выше ответы.
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
    }
}
Ответ 15
Еще одно простое решение отключить прокрутку на определенной странице (в этом примере на стр. 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;
}
Ответ 16
 Если вы пишете галерею изображений с помощью ImageView и ViewPager, которые поддерживают масштабирование и панорамирование, вы увидите простое решение, описанное здесь: Реализация масштабируемого ImageView путем расширения стандартного ViewPager в Phimpme Android (и в примере Github - PhotoView). Это решение не работает только с ViewPager.
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;
        }
    }
}
Ответ 17
В kotlin мы можем решить эту проблему, создав собственный виджет, наследующий класс ViewPager, и добавив значение флага для управления поведением свайпов.
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
<your.package.NoSwipePager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/tab_layout" />
 Отключить смахивание программно. Если kotlin-android-extensions плагин применяется в build.gradle пролистывание может быть отключено путем записи ниже коды.
view_pager.pagingEnabled = false
В противном случае мы можем отключить считывание с помощью кода ниже:
val viewPager : ViewPager = findViewById(R.id.view_pager)
viewPager.pagingEnabled = false
Ответ 18
Если вы хотите реализовать то же самое для Android в Xamarin, вот перевод на С#
Я решил назвать атрибут "ScrollEnabled". Поскольку iOS использует только одно и то же имя. Таким образом, у вас есть равное именование на обеих платформах, что упрощает разработку для разработчиков.
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:
<?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>
Ответ 19
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;
                                         }
                                     });
Ответ 20
Ни один из приведенного выше кода не работает гладко. Я попробовал это
<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>
Ответ 21
 вот моя реализация 
 что если вы хотите отключить анимацию смахивания, вы можете использовать swipeListener влево и вправо и по-прежнему хотите прокрутить пальцем, но без анимации
 1-Переопределение Viewpager метод onInterceptTouchEvent и onTouchEvent
 2- создайте свой собственный GestureDetector
 3- обнаруживает жест смахивания и использует 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 установить swipeListener
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);
            }
             ...
           }
Ответ 22
Я просто немного настроил видовой пейджер и легко отключил смахивание.
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);
}
}
Ответ 23
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
            }
        })

