【问题标题】:Android viewpager detect swipe beyond the boundsAndroid viewpager检测滑动超出范围
【发布时间】:2014-09-17 11:17:59
【问题描述】:

在我的 Android 应用程序中,我使用 viewpager 进行图像滑动。我的要求是,如果用户滑出第一页和最后一页,则活动应该完成。

我已经接受了这个example。但是我的活动中没有调用方法setOnSwipeOutListener

这是我的自定义视图寻呼机类:

public class CustomViewPager extends ViewPager {

    public CustomViewPager(Context context) {
        super(context);
    }

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    float mStartDragX;
    OnSwipeOutListener mListener;

    public void setOnSwipeOutListener(OnSwipeOutListener listener) {
        mListener = listener;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        float x = ev.getX();
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            mStartDragX = x;
            break;
        case MotionEvent.ACTION_MOVE:
            if (mStartDragX < x && getCurrentItem() == 0) {
                mListener.onSwipeOutAtStart();
            } else if (mStartDragX > x
                    && getCurrentItem() == getAdapter().getCount() - 1) {
                mListener.onSwipeOutAtEnd();
            }
            break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    public interface OnSwipeOutListener {
        public void onSwipeOutAtStart();

        public void onSwipeOutAtEnd();
    }

} 

在我的活动类下面,我在我的自定义 viewpager 类上调用 setOnSwipeOutListener 方法,但它没有被调用。

myPager = (CustomViewPager) findViewById(R.id.home_pannels_pager);

.......

myPager.setOnSwipeOutListener(new OnSwipeOutListener() { // the method never called
    @Override
    public void onSwipeOutAtStart() {
        Log.e("swipe Out At Start ", "swipe out");
    }

    @Override
    public void onSwipeOutAtEnd() {
        Log.e("swipe Out At End ", "swipe end");
    }
});

myPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
    @Override
    public void onPageSelected(int po) {
        Log.e("positon", ""+po);
    }
});

请帮助我检测用户是否滑动到第一页和最后一页以关闭此活动以及如何从代码中调用该方法。

【问题讨论】:

  • “我的要求是,如果用户滑出第一页和最后一页,活动应该完成”——恕我直言,从用户体验的角度来看,这是可怕的。
  • @CommonsWare 为什么会很可怕?当您在 Onboarding 中使用它时,人们一直向下滑动到最后一页,在最后一页上,他们必须点击按钮或执行不同的操作。相反,如果他们可以滑动并结束入职,那对他们来说不是更容易吗?
  • @GokhanArik 因为用户很少能返回到入职屏幕。有了你的提议,他们刷,刷,刷,哎呀,现在他们不能回去了,因为他们刷了太多次了。我的评论不是专门针对入职的,但即使在您的情况下我仍然不会这样做。

标签: android android-viewpager


【解决方案1】:

就我而言,onInterceptTouchEvent 不起作用。我用 onTouchEvent 改变了方法,它正在工作。原解决方案来自tjlian616

    @Override
public boolean onTouchEvent(MotionEvent ev){
    if(getCurrentItem()==getAdapter().getCount()-1){
        final int action = ev.getAction();
        float x = ev.getX();
        switch(action & MotionEventCompat.ACTION_MASK){
        case MotionEvent.ACTION_DOWN:
            mStartDragX = x;
            break;
        case MotionEvent.ACTION_MOVE:
            break;
        case MotionEvent.ACTION_UP:
            if (x<mStartDragX){
                mListener.onSwipeOutAtEnd();
            }else{
                mStartDragX = 0;
            }
            break;
        }
    }else{
        mStartDragX=0;
    }
    return super.onTouchEvent(ev);
}    

【讨论】:

    【解决方案2】:

    我也使用了this SO answer 的代码。确保对活动课程进行必要的更改。这就是我所做的......

    我将活动更改为implements CustomViewPager.OnSwipeOutListener

    在我的活动中,在我的mPager = (CustomViewPager) findViewById(R.id.pager); 行之后,我调用 mPager.setOnSwipeOutListener(this);

    您需要做的就是在您的活动中覆盖onSwipeOutAtStart()onSwipeOutAtEnd() 方法。

    【讨论】:

      【解决方案3】:

      我更改了 M.A.Murali 的代码:

      public class CheckBoundsPager extends ViewPager {
          public CheckBoundsPager(Context context) {
              super(context);
          }
      
          public CheckBoundsPager(Context context, AttributeSet attrs) {
              super(context, attrs);
      
          }
      
          OnSwipeOutListener mListener;
      
          public void setOnSwipeOutListener(OnSwipeOutListener listener) {
              mListener = listener;
          }
      
          private float mStartDragX;
          private float mStartDragY;
          private float MIN_MOVE=50; //minimal movement in px - change it to you value
      
      
          @Override
          public boolean onInterceptTouchEvent(MotionEvent ev) {
              float x = ev.getX();
              float y = ev.getY();
              switch (ev.getAction()) {
                  case MotionEvent.ACTION_DOWN: {
                      //here we set x and y on user start drag
                      mStartDragX = x;
                      mStartDragY = y;
      
                      }
                      break;
                  case MotionEvent.ACTION_MOVE: {
      
                      //most important to check if x drag is more than y
                      float xDiff=Math.abs(mStartDragX-x);
                      float yDiff=Math.abs(mStartDragY-y);
      
                      //added condition if swipe y is less than x
                      if (mStartDragX < x-MIN_MOVE && xDiff>yDiff &&  getCurrentItem() == 0) {
                          mListener.onSwipeOutAtStart();
                      } else if (mStartDragX > x+MIN_MOVE
                              && xDiff>yDiff && getCurrentItem() == getAdapter().getCount() - 1) {
                          mListener.onSwipeOutAtEnd();
                      }
                      }
                      break;
              }
              return super.onInterceptTouchEvent(ev);
          }
      
          public interface OnSwipeOutListener {
      
              public void onSwipeOutAtStart();
      
              public void onSwipeOutAtEnd();
          }
      }
      

      此解决方案检查我们是向左还是向右拖动,并且我们的拖动移动是在 x 轴上。记得更改MIN_MOVE

      【讨论】:

      • 欢迎来到 StackOverflow。请仅显示需要更改的内容,而不是包括所有 OP 的问题。这将有助于未来有相同问题的人更好地了解您是如何解决问题的。
      【解决方案4】:

      *您可以通过执行 OnPageChangeListener 来实现这一点

      http://developer.android.com/reference/android/support/v4/view/ViewPager.OnPageChangeListener.html

      myPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
          @Override
          public void onPageScrolled(int i, float v, int i2) {
      
          }
          @Override
          public void onPageSelected( int i) {
            if(i == 0 || i == list.size()- 1){
               finish();
            }
          }
          @Override
          public void onPageScrollStateChanged(int i) {
          }
      });*
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-12
        相关资源
        最近更新 更多