我正在使用自定义方向ViewPager。我在Viewpager中有像Viewpager这样的流程,因此我必须禁用或启用父ViewPager才能使子寻呼机工作。我面临的问题是,如果我将方向设置为单侧,即左/右,然后在滚动,它仍然以小的抖动移动到该方向,即每次滑动10,20 dp。以下是代码,似乎在不正确的条件下拦截问题。
public class DirectionalViewPager extends ViewPager {
private static float DIRECTION_THRESHOLD; //The slop
float diffX, diffY;
private float initialXValue;
private float initialYValue;
private SwipeDirection direction;
private ScrollerCustomDuration mScroller = null;
public DirectionalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.direction = SwipeDirection.HORIZONTAL;
DIRECTION_THRESHOLD = context.getResources().getDimension(R.dimen.small_spacing);
postInitViewPager();
}
/**
* Override the Scroller instance with our own class so we can change the
* duration
*/
private void postInitViewPager() {
try {
Field scroller = ViewPager.class.getDeclaredField("mScroller");
scroller.setAccessible(true);
Field interpolator = ViewPager.class.getDeclaredField("sInterpolator");
interpolator.setAccessible(true);
mScroller = new ScrollerCustomDuration(getContext(),
(Interpolator) interpolator.get(null));
scroller.set(this, mScroller);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Set the factor by which the duration will change
*/
public void setScrollDurationFactor(double scrollFactor) {
mScroller.setScrollDurationFactor(scrollFactor);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (isSwipeAllowed(ev) && ev.getActionMasked() != MotionEvent.ACTION_DOWN
&& ev.getActionMasked() != MotionEvent.ACTION_UP)
return true;
else
return super.onInterceptTouchEvent(ev);
//return isSwipeAllowed(ev) && super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return isSwipeAllowed(ev) && super.onTouchEvent(ev);
}
private boolean isSwipeAllowed(MotionEvent event) {
if (this.direction == SwipeDirection.ALL) return true;
if (direction == SwipeDirection.NONE)//disable any swipe
return false;
int action = event.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
initialXValue = event.getX();
initialYValue = event.getY();
return true;
} else if (action == MotionEvent.ACTION_MOVE) {
try {
diffX = event.getX() - initialXValue;
diffY = event.getY() - initialYValue;
boolean isVertical = true;
boolean isAboveThreshold = Math.abs(diffX) > DIRECTION_THRESHOLD;
if (Math.abs(diffY) >= DIRECTION_THRESHOLD || Math.abs(diffX) >= DIRECTION_THRESHOLD)
isVertical = Math.abs(diffY) >= Math.abs(diffX);
if (diffX < 0 && direction == SwipeDirection.RIGHT) {
// left intercept is detected
return false;
} else if (diffX > 0 && direction == SwipeDirection.LEFT) {
// right intercept is detected
return false;
} else if (isVertical && direction == SwipeDirection.HORIZONTAL) {
// vertical swipe is detected. Lets intercept by returning true
return false;
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
return true;
}
public SwipeDirection getSwipeDirection() {
return direction;
}
public void setSwipeDirection(SwipeDirection direction) {
this.direction = direction;
}
/**
* Select the direction that you want to enable, others will be ignored
*/
public enum SwipeDirection {
ALL(0),
NONE(1),
LEFT(2),
RIGHT(3),
UP(4),
DOWN(5),
VERTICAL(6),
HORIZONTAL(7),;
private final int mType;
SwipeDirection(int type) {
mType = type;
}
public int getType() {
return mType;
}
}
}