我正在使用 ViewPager(支持库)。我想知道每次 ViewPager 更改可见页面时,它是向左还是向右滚动。
请给我一个解决方案。也欢迎任何推荐。
谢谢
我正在使用 ViewPager(支持库)。我想知道每次 ViewPager 更改可见页面时,它是向左还是向右滚动。
请给我一个解决方案。也欢迎任何推荐。
谢谢
设置setOnPageChangeListener
为您的ViewPager
保持一个全局变量为
private int lastPosition = 0;
并且在
@Override
public void onPageSelected(int arg0) {
if (lastPosition > position) {
System.out.println("Left");
}else if (lastPosition < position) {
System.out.println("Right");
}
lastPosition = position;
}
这不是一个完美的解决方案,但这里有一种方法可以在您开始滑动时检查滑动方向:
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;
}
}
});
编辑:有一种更优雅的方法涉及使用 aViewPager.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.
}
}
}
您可以从以下内容了解更多信息:将 ViewPager 用于屏幕幻灯片
与 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;
}
}
});
您可以保留类成员变量以保存上次访问的页面
private int mLastVisitedPageIndex = 0;
然后使用以下功能检查方向
@Override
public void onPageSelected(int i) {
boolean isMovingForward = mLastVisitedPageIndex < i?true:false;
//Use isMovingForward variable anywhere now
mLastVisitedPageIndex = i;
}
用那个
@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
}
}
使用ViewPager.OnPageChangeListener
界面。您可以使用传递给的位置参数onPageSelected
并将其与先前的值进行比较,以确定ViewPager
滚动的方式。
private float sumPositionAndPositionOffset;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
boolean isSwipeToLeft = position + positionOffset > sumPositionAndPositionOffset;
sumPositionAndPositionOffset = position + positionOffset;
}
我用这个实现解决了这个问题。希望能帮助到你。
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 {
}
}
我们也可以使用自定义 Viewpager 来做到这一点,它可以包含 swipeLeft() 和 swipeRight() 方法,并且它的 onTouchEvent(MotionEvent event) 方法可以包含 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();
}
}
道歉 - 因为我发现了一个错误,所以不得不编辑答案。这是改进的解决方案:
该解决方案将当前页面索引与先前选择的页面索引 (previousPageIndex) 进行比较
newPageIndex 表示即将滚动到的页面。
Condition (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;
}
}
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;
}
}
});
如果您担心位置偏移在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
}
}
这是一种在滚动方向发生时可以知道滚动方向的方法。您所要做的就是OnPageChangeCallback()
在ViewPager
. ViewPager
您保存in的当前页面OnPageSelected()
并将其与 的position
参数进行比较OnPageScrolled()
。如果当前页面小于或等于 ,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
}
}
})
pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(position == pager.getCurrentItem()){
// Move Right
}
else{
// Move Left
}
}