如何在安卓中禁用或启用ViewPager的滑动?

83

我想做什么:我正在尝试在程序运行时以编程方式启用/禁用页面切换。

例如:当进行流程时,如果我检查一个条件并且如果它返回true则启用页面切换,如果条件返回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”,用户就不能通过滑动分页了。


上述方法的问题:我无法在流程中设置属性,即......我要么可以启用滑动,要么可以禁用滑动。但是我无法根据条件执行此操作


问题:

  1. 如果可以,在其他方式中如何实现我的目标?
  2. 还是不可能的?

能否通过数据绑定在流程上设置属性? - oldergod
尝试使用https://dev59.com/AGsz5IYBdhLWcg3wj4ra#42687397。 - Pradeep Kumar Kushwaha
9个回答

82

对我来说最好的解决方案。 - 首先,您需要创建一个像这样的类:

public class CustomViewPager extends ViewPager {
  private Boolean disable = false;
  public CustomViewPager(Context context) {
      super(context);
  }
  public CustomViewPager(Context context, AttributeSet attrs){
      super(context,attrs);
  }
  @Override
  public boolean onInterceptTouchEvent(MotionEvent event) {
     return !disable && super.onInterceptTouchEvent(event);
  }

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

  public void disableScroll(Boolean disable){
      //When disable = true not work the scroll and when disble = false work the scroll
      this.disable = disable;
  }
}

-然后在您的布局中更改此内容:<android.support.v4.view.ViewPager<com.mypackage.CustomViewPager

-最后,您可以禁用它:view_pager.disableScroll(true); 或启用它:view_pager.disableScroll(false);

希望这能对您有所帮助 :)


谢谢Alberto :) - Praveen Kumar Verma
1
在调用禁用滚动方法后,不要忘记调用**viewPager.invalidate()**方法,因为它会立即禁用滑动。 - Ritesh Adulkar
使用此解决方案,如果 disable == true,ViewPager 中的视图将不会接收任何输入。覆盖 onInterceptTouchEvent() 不是正确的解决方案。 - Alex Semeniuk
我更喜欢在这里使用boolean,而不是Boolean。 - hgoebl
谢谢。您的答案帮助我改进了一个正在运行的功能。 - AndyN
对于 Viewpager2,您不需要自定义类,您可以使用 myViewPager2.setUserInputEnabled(false); 来简单禁用滚动。 - Khizar Hayat

65

通过编程禁用滑动操作 -

    final View touchView = findViewById(R.id.Pager); 
    touchView.setOnTouchListener(new View.OnTouchListener() 
    {         
        @Override
        public boolean onTouch(View v, MotionEvent event)
        { 
           return true; 
        }
     });

然后手动使用它进行滑动

touchView.setCurrentItem(int index);

60
仍然允许视图页部分滑动(如1%)后才停止。这看起来很不美观。 - IgorGanapolsky
8
他的解决方案是可行的,只是不完整。你还应该覆盖 onInterceptTouchEvent(MotionEvent event) 方法。这样可以实现你想要的效果,而又不会产生1%的问题。 - portfoliobuilder
2
无法覆盖该方法。 - Animesh Mangla
它能够工作,但启用后,滑动非常糟糕和缓慢。 - faeze saghafi
6
这个解决方案是完全错误的,为什么会有那么多星级评价。它看起来确实很丑,只有1%的滑动效果。也许我们应该扩展viewpager,并重写onInterceptTouchEvent方法。 - Anton Kizema
显示剩余2条评论

22

在您的自定义视图页适配器中,覆盖那些ViewPager中的方法。

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

要启用此功能,只需返回每个 super 方法:

super.onInterceptTouchEvent(event)super.onTouchEvent(event)


6
如果您只是因为需要非可滑动行为而想要扩展它,那么您不需要这样做。ViewPager2提供了一个很好的属性叫做:isUserInputEnabled

6
禁用滑动功能
mViewPager.beginFakeDrag();

启用滑动功能

如果 (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();


将会出现这个问题 https://github.com/JakeWharton/ViewPagerIndicator/issues/412 - Mia
请问您能详细说明您的查询吗? - Sanjay Bhalani
我尝试使用这个解决方案,但在调用endFakeDrag时会抛出NullPointerException。 - Mia
尝试使用条件语句,例如: if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag(); - Sanjay Bhalani
这并不能阻止滑动,只是让它变得丑陋。 - Harsha Bhadra

5

禁用viewpager2中的滑动,请使用:

viewPager2.setUserInputEnabled(false);

为了在ViewPager2中启用滑动,请使用以下方法:
viewPager2.setUserInputEnabled(true);

viewPager2.isUserInputEnabled = false // 禁用滑动... - sandip

3

在我的情况下,简化的解决方案效果很好。 覆盖方法必须在您的自定义ViewPager适配器中,以覆盖TouchEvent监听器并使其冻结。

@Override
public boolean onTouchEvent(MotionEvent event) {
    return this.enabled && super.onTouchEvent(event);

}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    return this.enabled && super.onInterceptTouchEvent(event);

}

提供有关所提供解决方案的说明。 - Anantha Raju C
1
@AnanthaRajuC 提供的 :) - Eric
使用这个解决方案,如果 this.enabled == false,ViewPager 中的视图将不会接收任何输入。覆盖 onInterceptTouchEvent() 不是正确的解决方案。 - Alex Semeniuk

2
我发现另一种解决方案对我有效,请按照此链接操作: https://dev59.com/AGsz5IYBdhLWcg3wj4ra#42687397 它基本上是通过覆盖方法canScrollHorizontally来禁用手指滑动。但是,setCurrentItem仍然可以使用。

“canScrollHorizontally()”方法在当前情况下没有任何效果。 当滑动发生时,甚至不会被调用。 - Alex Semeniuk

1
这对我有效。
   ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            // disable swipe
            if(!swipeEnabled) {
                if (viewPager.getAdapter().getCount()>1) {
                    viewPager.setCurrentItem(1);
                    viewPager.setCurrentItem(0);
                }
            }
        }
        public void onPageScrollStateChanged(int state) {}
        public void onPageSelected(int position) {}
    };
    viewPager.addOnPageChangeListener(onPageChangeListener);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接