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

Nic*_*las 32 android

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

Flá*_*ria 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();
    }

}
Run Code Online (Sandbox Code Playgroud)


tjl*_*616 17

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

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

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();
}
Run Code Online (Sandbox Code Playgroud)


spa*_*ker 16

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

public class CustomViewPager extends android.support.v4.view.ViewPager {

    float mStartDragX;
    OnSwipeOutListener mOnSwipeOutListener;

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

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

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

    private void onSwipeOutAtStart() {
        if (mOnSwipeOutListener!=null) {
            mOnSwipeOutListener.onSwipeOutAtStart();
        }
    }

    private void onSwipeOutAtEnd() {
        if (mOnSwipeOutListener!=null) {
            mOnSwipeOutListener.onSwipeOutAtEnd();
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch(ev.getAction() & MotionEventCompat.ACTION_MASK){
            case MotionEvent.ACTION_DOWN:
                mStartDragX = ev.getX();
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev){

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

    }

    public interface OnSwipeOutListener {
        void onSwipeOutAtStart();
        void onSwipeOutAtEnd();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 做一个款待(每次刷卡只有一个回调!).顺便说一下,你可能想让你的活动`实现CustomViewPager.OnSwipeOutListener`,并且在你的活动中,不要忘记在你的CustomViewPager对象上调用`myCustomViewPager.setOnSwipeOutListener(this);`. (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) {
    }
});
Run Code Online (Sandbox Code Playgroud)

  • 方法`setOnPageChangeListener()`在较新的SDK中已弃用,并被`addOnPageChangeListener()`替换. (5认同)