ViewPager检测用户何时尝试滑出界限

时间:2012-11-12 15:46:42

标签: android

我正在使用由6页组成的ViewPager来显示一些数据。我希望能够在用户位于0位置时尝试调用方法并尝试向右滑动(向后)或在位置5处尝试向左滑动(向前),即使这些页面不存在更多页面方向。有什么方法可以听这些场景吗?

5 个答案:

答案 0 :(得分:48)

扩展ViewPager并覆盖onInterceptTouchEvent(),如下所示:

public class CustomViewPager extends ViewPager {

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

}

答案 1 :(得分:17)

FlávioFaria的回答对我不起作用。我在onInterceptTouchEvent()中遇到的唯一事件是ACTION_DOWN事件。所以我重写了onTouchEvent()方法以使其工作。

这是代码。请注意,我在侦听器中只有onSwipeOutAtEnd()。您可以添加代码以支持在第一个维度上滑动。

public class CustomViewPager extends ViewPager {

float mStartDragX;
OnSwipeOutListener mListener;


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

@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);
}    
public interface OnSwipeOutListener {
    public void onSwipeOutAtEnd();
}

答案 2 :(得分:15)

如何在ViewPager上设置OnPageChangeListener?然后,您可以修改导航箭头或onPageScrolled中的任何内容。

viewPager.setOnPageChangeListener(new OnPageChangeListener() {
    @Override
    public void onPageSelected(int position) {
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            updateNavigationArrows();
    }

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

答案 3 :(得分:15)

非常感谢@Flavio,虽然我不得不对他的代码进行一些更改,因为回调方法被触发两次,我还添加了代码以检查是否有任何已注册的侦听器,以避免在没有侦听器时应用程序崩溃注册。这是我用来使其工作的代码,包括onSwipeOutAtStart和onSwipeOutAtEnd:

<upsource_home>\bin\upsource.bat configure --listen-port 1111 --base-url https://upsource.mydomain.com/

答案 4 :(得分:4)

我想知道它对别人有用,它不适合我。

onInterceptTouchEvent()只需ACTION_DOWN次事件。虽然onTouchEvent()一次只能处理一个事件ACTION_DOWNACTION_UP和其他事件。

我必须覆盖onInterceptTouchEvent()onTouchEvent()才能使其正常运行。 ACTION_DOWN的{​​{1}}抓取初始onInterceptTouchEvent触摸点,X抓取最终OnTouchEvent点。我把它比作检测滑动方向。

获取触摸的初始X值:

X2

从tjlian616的代码中,float x1 = 0; @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch(ev.getAction() & MotionEventCompat.ACTION_MASK){ case MotionEvent.ACTION_DOWN: x1 = ev.getX(); break; } return super.onInterceptTouchEvent(ev); } 听取onTouchEvent()并获取其最后ACTION_UP值。 虽然我已将当前项目的值设置为0以在启动侦听器处滑出。比较它并添加了听众。

X