我有ViewPager,在它下面有10个按钮。通过单击按钮(例如#4),寻呼机可通过mPager.setCurrentItem(3);立即转到第4页。但是,我想通过水平滑动手指来禁用分页。因此,只能通过单击按钮来完成分页。
那么,如何禁用手指滑动?

评论

首先使用ViewFlipper怎么样?这将使您免于头痛。

使用ViewPager2,禁用滑动仅需一行代码:stackoverflow.com/questions/54978846/…

#1 楼

您需要继承ViewPageronTouchEvent包含很多您不想更改的好东西,例如允许子视图得到触摸。 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中,旨在占据整个屏幕,这就是为什么layout_weight为1且layout_height为0dp的原因。
setMyScroller();方法用于平滑过渡

评论


@louielouie附带说明:有什么特殊的原因,为什么您选择0dp height / 1权重解决方案而不是match_parent高度来实现全屏效果?这样可以提高性能吗?

–ubuntudroid
13年8月21日在7:28



使用键盘的向左/向右键(在模拟器中尝试)时,此答案不会阻止页面滑动。对于触摸设备来说可能不是问题,但对于电视和笔记本电脑来说可能就是一个问题。

– Vincent Mimoun-Prat
2014年8月3日13:50

@MarvinLabs @Thorbear通过键盘禁用页面滚动的正确方法是重写exe​​cuteKeyEvent()。这是然后调用allowScroll()的方法。 //绝对不要使用键盘的LEFT,RIGHT,TAB和SHIFT + TAB键进行刷卡@Override public boolean executeKeyEvent(KeyEvent event){return false; }

–araks
2015年3月9日17:14



好吧,这也会禁用垂直滚动...如果使用列表视图,这是不好的。

–maysi
15年9月20日在13:09

我希望Google可以提供一种方法,为我们提供有关如何处理触摸/滑动的接口方法,因为我认为这不会造成伤害?

–霓虹灯Warge
2015年11月14日下午13:58

#2 楼

ViewPager的更通用扩展是创建SetPagingEnabled方法,以便我们可以即时启用和禁用分页。
要启用/禁用刷卡,只需覆盖以下两种方法:onTouchEventonInterceptTouchEvent。如果禁用了分页,则两者都将返回“ 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;
    } 
}


然后选择此选项,而不是XML中的内置viewpager

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


您只需要用setPagingEnabled调用false方法,用户将无法滑动以进行分页。

评论


非常适合具有多个子视图的视图,其中一个子视图使用水平滚动(例如,AChartEngine图表)。在我的片段中,我使用了一个回调到我的活动,告诉它根据用户是否触摸(ACTION_MOVE)图表还是将其离开(ACTION_CANCEL)来关闭或关闭分页。非常感谢!

– Riper
2014年2月14日23:22

您可以通过启用返回&& super.onTouchEvent(event);来简化onTouchEvent和onInterceptTouchEvent方法。

–nbarraille
2014年8月16日在2:38



我还建议将字段名称从“已启用”更改为“ swipePageChangeEnabled”或类似名称。编写代码一个月后,您几乎不记得“启用”的含义了,尤其是当您的类称为“ CustomViewPager”时,不清楚什么是自定义。这也是样式的问题,但是如果您不想以无法支持​​的项目结束,样式就很重要,完全重写比修复它容易。

–bytefu
2015年4月6日在9:07



在哪里调用setPagingEnabled? ._。

– Ntikki
2015年11月6日14:24

@Ntikki,您可以像这样声明ViewPager后调用setPagingEnabled()方法:CustomViewPager yourCustomViewPager =(CustomViewPager)findViewById(R.id.yourCustomViewPager); yourCustomViewPager.setPagingEnabled(false)

– blueware
16-10-3在11:53



#3 楼

最简单的方法是访问setOnTouchListener并为true返回ViewPager

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


评论


有时不起作用。我正在使用带有FragmentPagerAdapter和几个Fragment的ViewPager。将OnTouchListener设置为寻呼机后,如果我向左跳,则UI仍将向左移动一点。

–邹Chris
13年2月26日在6:24

当您添加pager.setCurrentItem(pager.getCurrentItem());时,它将起作用。返回true之前。

– dng
13年9月18日在11:14

似乎为我工作。为了解决一些布局问题,我有一个公共int getItemPosition(Object object){return POSITION_NONE; }在我的适配器中,这会强制重新创建页面并可能还会解决其他问题。

– r-hold
2014年4月29日在22:35



这是部分有效的解决方案。水平滑动会以某种奇怪的方式处理。我在ViewPager中使用Drag'n Drop Gridview对此进行了测试。使用此解决方案拖动时,从左向右拖动以及从右向左拖动都会失败。我个人认为Rajul的方法是最好的。

–Ton Snoei
2014-12-18 14:03

在Android 6上(尚未在任何其他版本上进行测试),如果您多次单击并向左拖动,则可以看到视图寻呼机向左滑动。这很有趣。

– Hola Soy Edu Feliz Navidad
3月2日14:20

#4 楼

现在,我们无需创建自定义ViewPager
新的ViewPager2名称android中可用的视图

垂直方向支持




ViewPager2支持垂直除了传统的水平寻呼之外,还可以进行寻呼。您可以通过设置ViewPager2属性来启用android:orientation元素的垂直分页


使用XML

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


使用代码

要禁用viewpager2中的滑动,请使用
viewPager2.setUserInputEnabled(false);

要启用viewpager2中的滑动,请使用
viewPager2.setUserInputEnabled(true);

有关更多信息,请检查此内容

ViewPager2
深入了解ViewPager2
动手使用ViewPager2

更新


请检查:从ViewPager迁移到ViewPager2


有关完整示例,请检查此在Android中使用ViewPager2




评论


很好,但看起来仍然不完整。我用5个不同的片段进行了尝试,在页面之间切换后,片段中的一种丢失了,即视图既没有还原也没有重新膨胀

– Toochka
19 Mar 30 '19 at 22:10

@Toochka很遗憾听到对我来说一切正常,您可以在这里找到示例工作代码stackoverflow.com/a/54643817/7666442如果可能,请共享您的代码

–问Nilesh
19 Mar 30 '19在22:14

我可以使用此方法成功禁用对ViewPager2的滑动

–voghDev
19/12/16在11:23

@voghDev很高兴听到

–问Nilesh
19/12/16在13:01

@PhaniRithvij,请检查此答案stackoverflow.com/a/54643817/7666442我已添加了所有详细信息如何在RecyclerView.Adapter中使用viewpager2

–问Nilesh
19/12/23在4:58

#5 楼

如果您将ViewPager本身放在另一个ViewPager中,则仅覆盖onTouchEventonInterceptTouchEvent是不够的。子级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);
    }

}


评论


谢谢,这在另一个ViewPager内的ViewPager上效果很好。

–费尔南达·巴里(Fernanda Bari)
16年1月14日在18:01

这适用于我,也适用于另一个ViewPager中的ViewPager。在这种情况下,正确的解决方案对我不起作用。

–拉斐尔·鲁伊斯·穆尼兹(Rafael RuizMuñoz)
16年2月20日在22:03

在选项卡中使用时也停止动画。

– Rishabh Srivastava
17年6月19日在6:42

如果禁用它并想启用它,那么在哪里可以使事件调用setSwipeLocked(false)?

–拉维·亚达夫(Ravi Yadav)
19 Jun 10'在12:42



#6 楼

最好声明它为可样式化,因此您可以从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;
}


以及在您的values / 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属性。

#7 楼

如果从ViewPager扩展,则还必须按@araks先前指示的那样覆盖executeKeyEvent,因为某些设备(例如Galaxy Tab 4 10')在大多数情况下会显示这些按钮,设备从不显示它们:



评论


三星一直在为Android开发人员搞砸。

–toobsco42
16年8月13日在21:54

@ toobsco42在这种情况下,三星并不孤单。 SwiftKey(流行键盘应用程序)允许用户在其键盘上放置箭头。

–苏菲安
16年11月29日在15:14

如果您想阻止使用键盘/轨迹球的人向您的寻呼机付款,这也是解决方法。

–se22as
17年11月24日在17:55

#8 楼

禁用滑动

mViewPager.beginFakeDrag();


禁用滑动

mViewPager.endFakeDrag();


评论


这不是一个好的解决方案,因为它允许很小的移动量,至少在我的应用程序中。

–科拉斯
16年5月5日在20:36

#9 楼

我需要禁用在一个特定页面上的滑动,并给它一个漂亮的橡皮筋动画,方法如下:

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


评论


它一直等到下一页部分可见。将执行onPageSelected中下一页的代码。甚至下一页也会切换。因此,不需要此代码。

– CoolMind
18/12/13在16:41

#10 楼

我写了一个带有滑动控件的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

我在项目中使用了它,到现在为止效果很好。

评论


如果我在ViewPager中有一个按钮并且想要单击该怎么办?此解决方案使viewpager下面的所有内容停止点击。

–aimiliano
17年4月7日在20:30



我没有@aimiliano遇到的问题。我的ViewPager中有多个可单击的项目,并且在此解决方案中都可以正常工作。这对我来说很完美!

–兰迪
6月17日19:49

#11 楼

我知道发布此消息的时间太晚了,但这是实现目标的小技巧;)

只需在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
    }
});


对布局,它们的位置和行为有一点创意,您将学习找到一种方法来做任何您想像的事情:)

祝你好运!

评论


如果您不需要处理onClick事件,则更简单的方法是使用setClickable而不是setOnClickListener。

–混乱
17年2月19日在15:25

这会不会也阻止viewpager中的触摸?

– Android开发人员
17年5月21日在10:41

是的,它会。这是OP @androiddeveloper所需的预期行为

–迪努卡·杰伊(Dinuka Jay)
17年5月23日在2:42



@RickGrimesTheCoder我认为您不理解我的问题。我的意思是在viewpager片段中的视图。他们还会触摸吗?

– Android开发人员
17年5月23日在5:08

不,因为viewpager本身具有单击侦听器,所以它们不会。这仅适用于片段中没有交互元素的实例。例如,欢迎使用ViewPager,它会动态更改其片段@androiddeveloper

–迪努卡·杰伊(Dinuka Jay)
17年5月23日在7:36

#12 楼

我成功地使用了这堂课。需要重写exe​​cuteKeyEvent以避免在某些设备中使用箭头滑动或可访问性:

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


评论


有用。仅禁用滑动,并且启用了选项卡上的单击。 AS警告performPerform()方法不会被覆盖。

– CoolMind
18/12/14在7:38

#13 楼

在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" />
 


以编程方式禁用滑动。如果在build.gradle中应用了kotlin-android-extensions插件,则可以通过编写以下代码来禁用滑动。

view_pager.pagingEnabled = false


否则,我们可以使用以下代码来禁止滑动:

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


评论


重写onInterceptTouchEvent()将阻止子视图接收输入。在大多数情况下,这不是预期的行为。

– Alex Semeniuk
19年7月16日在14:55

@AlexSemeniuk在执行此操作后,您是否发现任何问题?我已经启用了对回收者视图项进行刷卡的某些操作,并且工作正常。因此,在我的情况下,实现效果很好。

– Sagar Chapagain
19年7月17日在4:42

Sagar Chapagain:或者,我做到了。我的每个页面都包含自定义视图,该视图以各种方式处理触摸(包括滚动,拖动,单击和长按)。不调用super.onInterceptTouchEvent(event)会导致这些视图不接收任何输入(这是onInterceptTouchEvent方法的已记录用途)。

– Alex Semeniuk
19年7月17日在11:08



如果是这种情况,您应该使用子片段并维护backstack。

– Sagar Chapagain
19年7月17日在11:13

这与当前问题有什么关系?片段放置在某些容器(即视图)中,它们自己的布局包含视图。无论ViewPager中包含什么内容,我都仍在处理以下事实:重写onInterceptTouchEvent()方法会阻止它(内容)接收输入。

– Alex Semeniuk
19年7月17日在11:45



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


评论


重写onInterceptTouchEvent()将阻止子视图接收输入。在大多数情况下,这不是预期的行为。

– Alex Semeniuk
19年7月17日在11:09

我能够与每个片段的子视图进行交互。不确定您指的是什么。

– Jeff Padgett
19年7月17日在19:38

#15 楼

尝试覆盖onInterceptTouchEvent()和/或onTouchEvent()并返回true,这将消耗寻呼机上的触摸事件。

评论


他不想返回true表示触摸事件已处理吗?

–第三版
2012-03-10 22:53

#16 楼

如果您使用的是ViewPager2,则只需使用:

viewpager.setUserInputEnabled(false);

从文档中:


启用或禁用用户启动的滚动。这包括触摸输入(滚动和甩动手势)和辅助功能输入。尚不支持禁用键盘输入。禁用用户启动的滚动时,通过setCurrentItem进行程序化滚动仍然有效。默认情况下,启用用户启动的滚动。


感谢:https://stackoverflow.com/a/61685871/9026710

#17 楼

禁用特定页面(在本例中为第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;
}


#18 楼

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


#19 楼

如果您使用支持缩放和平移的ImageViewViewPager来编写图库,请参见此处描述的简单解决方案:通过在Phimpme Android中扩展默认ViewPager(和Github示例-PhotoView)来实现可缩放的ImageView。此解决方案不适用于单独的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;
        }
    }
}


#20 楼

如果要在Xamarin中为Android实现相同的功能,这里是C#的翻译。

我选择将属性命名为“ ScrollEnabled”。因为iOS仅使用exat相同的命名。因此,您在两个平台上的名称都相同,从而使开发人员更容易。

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>


#21 楼

以上代码均无法正常工作。我尝试过此操作

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


#22 楼

这是我的实现方式
,如果要禁用滑动动画,则可以向左和向右使用swipeListener,但仍然希望通过手指滚动但不使用动画

1-覆盖Viewpager方法onInterceptTouchEventonTouchEvent

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

            }
             ...
           }


#23 楼

我只是稍微定制了viewpager并轻松禁用了滑动。

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


#24 楼

在科特林
viewPagerNavigation.isUserInputEnabled = false


#25 楼

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
            }

        })