如何知道viewpager是向左还是向右滚动?

时间:2012-12-02 07:55:48

标签: android android-viewpager

我正在使用ViewPager(支持库)。我想知道每次ViewPager更改可见页面时,它都向左或向右滚动。

请给我一个解决方案。欢迎任何推荐。

由于

15 个答案:

答案 0 :(得分:36)

setOnPageChangeListener设置为ViewPager

并在

@Override
public void onPageSelected(int arg0) {
    if(lastPage>arg0)
      {//User Move to left}
    else(lastPage<arg0) 
     {//User Move to right}
      lastPage=arg0
}

答案 1 :(得分:34)

这不是一个完美的解决方案,但是当您开始滑动时,这是检查滑动方向的方法:

new ViewPager.OnPageChangeListener() {

            private static final float thresholdOffset = 0.5f;
            private boolean scrollStarted, checkDirection;

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                if (checkDirection) {
                    if (thresholdOffset > positionOffset) {
                        Log.i(C.TAG, "going left");
                    } else {
                        Log.i(C.TAG, "going right");
                    }
                    checkDirection = false;
                }
            }

            @Override
            public void onPageSelected(int position) {}

            @Override
            public void onPageScrollStateChanged(int state) {
                if (!scrollStarted && state == ViewPager.SCROLL_STATE_DRAGGING) {
                    scrollStarted = true;
                    checkDirection = true;
                } else {
                    scrollStarted = false;
                }
            }
        });


编辑:这是一种更优雅的方法,涉及使用ViewPager.PageTransformer并检查其位置间隔:

...
myViewPager.setPageTransformer(true, new PageTransformer());
...

public class PageTransformer implements ViewPager.PageTransformer {
    public void transformPage(View view, float position) {

        if (position < -1) { 
            // [-00,-1): the page is way off-screen to the left.
        } else if (position <= 1) { 
            // [-1,1]: the page is "centered"
        } else { 
            // (1,+00]: the page is way off-screen to the right.           
        }
    }
}

您可以从以下网址了解详情:Using ViewPager for Screen Slides

答案 2 :(得分:14)

  1. 这是我在 ViewPager.OnPageChangeListener onPageScrolled()方法中的简单解决方案:
  2. enter image description here

答案 3 :(得分:6)

与GuilhE相同的解决方案,带有一个小修复,以避免在ViewPager中第一页(左侧没有页面)向左翻页(向右滑动)时出现误报。 它只是进行额外的检查,以确定滑动是否实际上已移动。

new ViewPager.OnPageChangeListener() {

  private static final float thresholdOffset = 0.5f;
  private static final int thresholdOffsetPixels = 1;
  private boolean scrollStarted, checkDirection;

  @Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    if (checkDirection) {
      if (thresholdOffset > positionOffset && positionOffsetPixels > thresholdOffsetPixels) {
        Log.i(C.TAG, "going left");
      } else {
        Log.i(C.TAG, "going right");
      }
    checkDirection = false;
  }
}

  @Override
  public void onPageSelected(int position) {}

  @Override
  public void onPageScrollStateChanged(int state) {
    if (!scrollStarted && state == ViewPager.SCROLL_STATE_DRAGGING) {
      scrollStarted = true;
      checkDirection = true;
    } else {
      scrollStarted = false;
    }
  }
 });

答案 4 :(得分:3)

您可以保留班级成员变量以保存上次访问过的页面

private int mLastVisitedPageIndex = 0;

然后使用以下功能检查方向

@Override
public void onPageSelected(int i) {
    boolean isMovingForward = mLastVisitedPageIndex < i?true:false;
    //Use isMovingForward variable anywhere now
    mLastVisitedPageIndex = i;
}

答案 5 :(得分:3)

使用

@Override
public void onPageSelected( int position )
{
    mCurrentFragmentPosition = position;
}
@Override
public void onPageScrolled( int position, float positionOffset, int positionOffsetPixels )
{
    boolean isGoingToRightPage = position == mCurrentFragmentPosition;
    if(isGoingToRightPage)
    {
        // user is going to the right page
    }
    else
    {
        // user is going to the left page
    }
}

答案 6 :(得分:2)

使用ViewPager.OnPageChangeListener界面。您可以使用传递给onPageSelected的position参数,并将其与之前的值进行比较,以确定ViewPager的滚动方式。

答案 7 :(得分:1)

我解决了这个实现的问题。希望它有所帮助。

public static final float EPSILON= 0.001f;

@Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {

    // initial position (positionOffset == 0)
    if (positionOffset < EPSILON) {
        mIsRight = positionOffset < 0.5;
        return;
    }

    // code here
    if (mIsRight) {
    } else {
    }
}

答案 8 :(得分:1)

我们也可以使用Custom Viewpager执行此操作,它可以包含swipeLeft()和swipeRight()方法,并且其onTouchEvent(MotionEvent事件)方法可以包含ACTION_MOVE和ACTION_CANCEL情况。

//如果有用,可以是代码。

public class SwiperViewPager extends ViewPager {

    SwiperListener mSwiperListener;
    private float downX;
    private float downY;
    private boolean isTouchCaptured;
    private float upX1;
    private float upY1;
    private float upX2;
    private float upY2;

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

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

    private float x1, x2;
    static final int min_distance = 20;

    boolean eventSent = false;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE: {
                downX = event.getX();
                downY = event.getY();

                if (!isTouchCaptured) {
                    upX1 = event.getX();
                    upY1 = event.getY();
                    isTouchCaptured = true;
                } else {
                    upX2 = event.getX();
                    upY2 = event.getY();
                    float deltaX = upX1 - upX2;
                    float deltaY = upY1 - upY2;
                    //HORIZONTAL SCROLL
                    if (Math.abs(deltaX) > Math.abs(deltaY)) {
                        if (Math.abs(deltaX) > min_distance) {
                            // left or right
                            if (deltaX < 0) {
                                if(!eventSent && mSwiperListener!=null){
                                    mSwiperListener.onLeftSwipe();
                                    eventSent = true;
                                }
                            }
                            if (deltaX > 0) {
                                if(!eventSent && mSwiperListener!=null){
                                    if(mSwiperListener.onRightSwipe()){
                                        eventSent = true;
                                        return false;
                                    }
                                }
                            }
                        } else {
                            //not long enough swipe...
                        }
                    }
                    //VERTICAL SCROLL
                    else {
                        if (Math.abs(deltaY) > min_distance) {
                            // top or down
                            if (deltaY < 0) {

                            }
                            if (deltaY > 0) {

                            }
                        } else {
                            //not long enough swipe...
                        }
                    }
                }
            }
            break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:{
                isTouchCaptured = false;
                eventSent = false;
            }

        }
        return super.onTouchEvent(event);
    }

    public void setmSwiperListener(SwiperListener mSwiperListener) {
        this.mSwiperListener = mSwiperListener;
    }

    public static interface SwiperListener {
        public boolean onLeftSwipe();

        public boolean onRightSwipe();
    }

}

答案 9 :(得分:1)

private float sumPositionAndPositionOffset;

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    boolean isSwipeToLeft = position + positionOffset > sumPositionAndPositionOffset;
    sumPositionAndPositionOffset = position + positionOffset;   
}

答案 10 :(得分:1)

歉意-我发现错误后必须编辑答案。 这是改进的解决方案:

该解决方案将当前页面索引与先前选择的一个(previousPageIndex)进行比较

newPageIndex表示将要滚动到的页面。

条件(positionOffset == 0)比较​​滚动是否结束

private int previousPageIndex = 0;
private int newPageIndex = -1;

private final int MOVE_DIRECTION_NONE = 0;
private final int MOVE_DIRECTION_LEFT = 1;
private final int MOVE_DIRECTION_RIGHT = 2;

private int moveDirection = MOVE_DIRECTION_NONE;


@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    super.onPageScrolled(position, positionOffset, positionOffsetPixels);

    if (moveDirection == MOVE_DIRECTION_NONE) {
        if (previousPageIndex  == position){
            moveDirection = MOVE_DIRECTION_LEFT;
            if (newPageIndex == -1) newPageIndex = previousPageIndex + 1;
        }  else {
            moveDirection = MOVE_DIRECTION_RIGHT;
            if (newPageIndex == -1) newPageIndex = previousPageIndex - 1;
        }
    }

    if (positionOffset == 0) {
        System.out.println("Reseting");
        previousPageIndex = position;
        moveDirection = MOVE_DIRECTION_NONE;
        newPageIndex = -1;
    }

    switch (moveDirection) {
        case MOVE_DIRECTION_LEFT:
            if (onPageChangingHandler != null) onPageChangingHandler.pageChanging(previousPageIndex, newPageIndex, positionOffset);
            System.out.println("Sliding Left | Previous index: " + previousPageIndex + " | New Index: " + newPageIndex + " | offset: " + positionOffset  + " | Position: " + position);
            break;
        case MOVE_DIRECTION_RIGHT:
            if (onPageChangingHandler != null) onPageChangingHandler.pageChanging(newPageIndex, previousPageIndex, positionOffset);
            System.out.println("Sliding Right | Previous index: " + previousPageIndex + " | New Index: " + newPageIndex + " | offset: " + positionOffset + " | Position: " + position);
            break;
        case MOVE_DIRECTION_NONE:
            System.out.println("Moving NONE");
            break;
    }
}

答案 11 :(得分:0)

viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

        private int mCurrentSelectedScreen;
        private int mNextSelectedScreen;
        private static final float thresholdOffset = 0.5f;
        private boolean scrollStarted=true, checkDirection=false;
        ArrayList<Integer> comp_ary=new ArrayList<Integer>();

        @Override
        public void onPageSelected(int arg0) {
        }

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

        //Log.e("positionOffsetPixels : "+positionOffsetPixels, "positionOffset : "+positionOffset);
        comp_ary.add(positionOffsetPixels);
             if (checkDirection) {
                    if (comp_ary.get(2) < comp_ary.get(comp_ary.size()-1)) {

                        Log.e("going left", "going left");
                    } else
                        if (comp_ary.get(2) > comp_ary.get(comp_ary.size()-1))
                    {

                        Log.e("going right", "going right");
                    }
                    checkDirection = false;
                    comp_ary=new ArrayList<Integer>();
                }
        }

        @Override
        public void onPageScrollStateChanged(int arg0) {




            if (!scrollStarted && arg0 == ViewPager.SCROLL_STATE_SETTLING) {
                scrollStarted = true;
                checkDirection = true;
            } else {
                scrollStarted = false;
            }


        }
    });

答案 12 :(得分:0)

轻拍如果您担心位置偏移量在取值后突然变为 0 > 0.9F

    private boolean LEFT_DAB; //left swipe
    private float offset; //current position offset
    private float take_off; //previous position offset
    private static final float quavo = 0.5F; //position offset threshold

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        super.onPageScrolled(position, positionOffset, positionOffsetPixels);

        offset = take_off > 0.9F ? take_off : positionOffset;
        take_off = positionOffset;

        if (offset > quavo) {
            LEFT_DAB = false;//RIGHT_SWIPE
        } else {
            LEFT_DAB = true;//LEFT_SWIPE
        }
    }

答案 13 :(得分:0)

这是一种可以在滚动发生时了解滚动方向的方法。您所要做的就是在 OnPageChangeCallback() 上设置一个 ViewPager。您将 ViewPager 的当前页面保存在 OnPageSelected() 中,并将其与 positionOnPageScrolled() 参数进行比较。如果当前页面小于或等于 position,则向右滚动,否则,向左滚动。

var currentPage = 0
viewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
    override fun onPageSelected(position: Int) {
        super.onPageSelected(position)
        currentPage = position
    }

    override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
        super.onPageScrolled(position, positionOffset, positionOffsetPixels)
        if (currentPage <= position) {
            // We are scrolling right
        } else {
            // We are scrolling left
        }
    }
})

答案 14 :(得分:-2)

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

            if(position  == pager.getCurrentItem()){
                // Move Right
            }
            else{
                // Move Left
            }

        }