Android viewpager检测超出边界的滑动

时间:2014-09-17 11:18:00

标签: android android-viewpager

在我的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);
    }
});

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

4 个答案:

答案 0 :(得分: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);
}    

答案 1 :(得分:0)

我还使用了this SO answer中的代码。确保对活动类进行必要的更改。这就是我做的......

我将活动改为implements CustomViewPager.OnSwipeOutListener

在我的活动中,在mPager = (CustomViewPager) findViewById(R.id.pager);行后,我打电话 mPager.setOnSwipeOutListener(this);

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

答案 2 :(得分:0)

我改变了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

答案 3 :(得分:-1)

*您可以通过实现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) {
    }
});*