【问题标题】:ViewPager disable swiping to a certain directionViewPager 禁止向某个方向滑动
【发布时间】:2013-09-06 14:19:38
【问题描述】:

我想禁用滑动,但仅限于右侧。我在this 答案中找到了一个可行的解决方案。不幸的是,这复制了整个ViewPager 源以实现目标。有没有只继承现有类而不重复的方法?

【问题讨论】:

  • 你一定要用vanilla ViewPager吗?
  • 如果有一个包含 ViewPager 的库,我可以顺便使用它。请注意,我想动态启用和禁用右滑动,而不仅仅是静态禁用它。
  • 我想您可以尝试覆盖 onTouchEvent 或 onInterceptTouchEvent 并尝试过滤掉您不希望它响应的触摸事件(其余部分调用 super)。
  • 实际上我必须复制所有内容,因为我想修改私有方法。 :(
  • 防止滑动真的很简单,一个方法调用。仅在一侧阻止它们可能会更加困难......

标签: android android-viewpager swipe


【解决方案1】:

我不确定这是否正是您所需要的: 我需要一个 viewpager 来创建一个具有用户无法通过的最大页面的向导。

最后解决方案是在适配器中。 我更改了 PagerAdapter 的计数,这样可以阻止用户传递最大页面:

@Override
public int getCount() {
    return mProgress; //max page + 1
}

当用户进入下一页时:

private void setWizardProgress(int progress) {
    if(progress > mProgress) {
        mProgress = progress;
        mWizardPagerAdapter.notifyDataSetChanged();
    }
}

这样,当用户处于最大页面时,他无法向右滚动。

【讨论】:

  • 谢谢!这是一个老问题,我已经解决了这个问题(通过删除ViewPager 并使用Fragment 动画,这样我就可以完全控制流程)。我认为你的解决方案很好,所以我接受了。 :)
  • 你是怎么做到的,你能分享一个sn-p吗?你是如何在这个例子中禁用右侧的交换的。
【解决方案2】:

这是一个可以禁用任何方向分页的 ViewPager 类。 查看所有answer here

public class CustomViewPager extends ViewPager {
    private float initialXValue;
    private SwipeDirection direction;

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.direction = SwipeDirection.all;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (this.IsSwipeAllowed(event)) {
            return super.onTouchEvent(event);
        }

        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (this.IsSwipeAllowed(event)) {
            return super.onInterceptTouchEvent(event);
        }

        return false;
    }

    private boolean IsSwipeAllowed(MotionEvent event) {
        if(this.direction == SwipeDirection.all) return true;

        if(direction == SwipeDirection.none )//disable any swipe
            return false;

        if(event.getAction()==MotionEvent.ACTION_DOWN) {
            initialXValue = event.getX();
            return true;
        }

        if(event.getAction()==MotionEvent.ACTION_MOVE) {
            try {
                float diffX = event.getX() - initialXValue;
                if (diffX > 0 && direction == SwipeDirection.right ) {
                    // swipe from left to right detected
                    return false;
                }else if (diffX < 0 && direction == SwipeDirection.left ) {
                    // swipe from right to left detected
                    return false;
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }

        return true;
    }

    public void setAllowedSwipeDirection(SwipeDirection direction) {
        this.direction = direction;
    }

【讨论】:

  • 这东西确实有效。 (虽然语法样式很糟糕)
  • @vedant1811 我有什么不好?
  • @lelloman 可能意味着缺少自动格式化,IsSwipeAllowed 带有一个大的首字母,没有抛出异常的 try-catch 以及那里的 printStackTrace,以及“this”在不必要的地方(以及覆盖方法实际上可以内联)。但无论如何,答案是有帮助的。
  • 嗨,@andre719mv 这适用于普通页面。但是如果页面包含 EditText 触摸被禁用所以......这个解决方案在这种情况下不起作用。
  • try-catch 块是不必要的。它里面的任何东西都不会抛出异常。
【解决方案3】:

另一种简单的方法是使用 setCurrentItem() 如果您点击某个位置,则可以滚动回所需的幻灯片。例如,这将只允许向前滑动:

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

    @Override
    public void onPageSelected(int position) {
        if(position < mProgress) {
            mViewPager.setCurrentItem(mProgress, true);
        } else {
            mProgress = position;
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {}
});

或者,如果您想要最大幻灯片:

if(position > 4) {
    mViewPager.setCurrentItem(4, true);
}

从技术上讲,此解决方案不会完全禁用滑动,因为当您进行滑动移动时,您仍会看到一小部分不允许的滑动。但对于某些应用程序,这可能是首选。

【讨论】:

    【解决方案4】:

    您可以尝试以下操作:

    第 1 步:创建一个新的自定义类,例如“CustomViewPager”。该类继承自“ViewPager”并包含一个名为“setPagingEnabled”的新自定义方法,目的是根据要求启用/禁用滑动。

    第 2 步: 覆盖两个方法:“onTouchEvent”和“onInterceptTouchEvent”。如果要完全禁用分页,两者都将返回“false”。

    第 3 步: 用自定义类替换布局文件上的“ViewPager”标签:

        <package_name.customviewpager 
         android:id="@+id/customViewPager" 
         android:layout_height="match_parent" 
         android:layout_width="match_parent" />
    

    第 4 步: CustomViewPager.java

        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 && detectSwipeToRight(event)) {
            return super.onTouchEvent(event);
        }
    
        return false;
    }
    
    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (this.enabled && detectSwipeToRight(event)) {
            return super.onInterceptTouchEvent(event);
        }
    
        return false;
    }
    
    // To enable/disable swipe 
    public void setPagingEnabled(boolean enabled) {
        this.enabled = enabled;
    }
    
    // Detects the direction of swipe. Right or left. 
    // Returns true if swipe is in right direction
    public boolean detectSwipeToRight(MotionEvent event){
    
     int initialXValue = 0; // as we have to detect swipe to right
     final int SWIPE_THRESHOLD = 100; // detect swipe
     boolean result = false;
    
            try {                
                float diffX = event.getX() - initialXValue;
    
                    if (Math.abs(diffX) > SWIPE_THRESHOLD ) {
                        if (diffX > 0) {
                            // swipe from left to right detected ie.SwipeRight
                            result = false;
                        } else {
                            // swipe from right to left detected ie.SwipeLeft
                            result = true;
                        }
                    }
                } 
             catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }
    

    【讨论】:

    • 我尝试了更新的答案。 diffX 始终为正数,因此该方法永远不会返回 true
    • 嗨,wonderCsabo:你有同样的解决方案吗?我也尝试了很多但仍然面临这种类型的问题。等待你的重播。提前致谢。
    • 这不会检测滑动,它只会检测第一个(以及每个后续的)运动事件 X 坐标是否大于 0。这应该始终返回 false,因为 X 始终为正数。跨度>
    • yes Hamid,因此它禁用了双向滑动。
    【解决方案5】:

    您可以使用beginFakeDrag()endFakeDrag() 方法。

    beginFakeDrag() 当你想禁用滑动时 如果你想再次启用,endFakeDrag()

    像这样:viewPager.beginFakeDrag();

    【讨论】:

      【解决方案6】:
      private float initialXValue;
      @Override
      public boolean onTouchEvent(MotionEvent event) {
          if (this.mEnabled) {
              return super.onTouchEvent(event);
          }
          if(event.getAction()==MotionEvent.ACTION_DOWN){
              initialXValue = event.getX();
          }else if(event.getAction()==MotionEvent.ACTION_MOVE){
              if(detectSwipeToRight(event)){
                  System.out.println("right swipe detected");
              }
          }
          return true;
      }
      
      private boolean detectSwipeToRight(MotionEvent event) {
          final int SWIPE_THRESHOLD = 100; // detect swipe
          boolean result = false;
      
          try {
              float diffX = event.getX() - initialXValue;
              if (Math.abs(diffX) > SWIPE_THRESHOLD) {
                  if (diffX < 0) {
                      // swipe from right to left detected ie.SwipeLeft
                      result = true;
                  }
              }
          } catch (Exception exception) {
              exception.printStackTrace();
          }
          return result;
      }
      

      【讨论】:

      • 如果您再解释一下代码,这将是一个更好的答案。
      【解决方案7】:

      您必须创建自己的 ViewPager 子类并覆盖 canScrollHorizo​​ntally 函数

      http://developer.android.com/reference/android/support/v4/view/ViewPager.html#canScrollHorizontally(int)

      【讨论】:

      • 然后试试canScroll方法,我用过,它被称为
      • 永远不会被调用
      猜你喜欢
      • 2013-11-05
      • 1970-01-01
      • 1970-01-01
      • 2015-12-03
      • 2014-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多