Android 弹性的Viewpager
TouchMoveHelper.java
import android.content.Context;
import android.graphics.PointF;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
public class TouchMoveHelper {
private PointF positionTemp;
private TouchEventAdapter touchEventAdapter;
//判断是否滑动的临界点
private float touchSlop;
public TouchMoveHelper(Context context) {
positionTemp = new PointF();
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
touchEventAdapter = new TouchEventAdapter() {
@Override
void onTouchDown() {
}
@Override
void onTouchUp() {
}
@Override
boolean onTouchMove(float offsetX, float offsetY) {
return false;
}
};
}
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
touchEventAdapter.onTouchDown();
recordPosition(ev);
}
return touchEventAdapter.onInterceptTouchEvent();
}
public boolean onTouchEvent(MotionEvent ev) {
boolean isDealTouch = false;
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
touchEventAdapter.onTouchUp();
break;
case MotionEvent.ACTION_MOVE:
isDealTouch = touchEventAdapter.onTouchMove(getOffset(ev.getRawX() - positionTemp.x), getOffset(ev.getRawY() - positionTemp.y));
recordPosition(ev);
break;
}
return isDealTouch;
}
public abstract static class TouchEventAdapter {
abstract void onTouchDown();
abstract void onTouchUp();
abstract boolean onTouchMove(float offsetX, float offsetY);
//因为没有拦截子view事件,只是额外处理viewpager的自身事件,所以默认为false,
boolean onInterceptTouchEvent() {
return false;
}
}
public void setTouchEventAdapter(TouchEventAdapter touchEventAdapter) {
this.touchEventAdapter = touchEventAdapter;
}
private float getOffset(float offset) {
if (Math.abs(offset) > touchSlop) {
return offset;
} else {
return 0;
}
}
private void recordPosition(MotionEvent ev) {
positionTemp.x = ev.getRawX();
positionTemp.y = ev.getRawY();
}
}
BounceBackViewPager.java
import android.content.Context;
import android.graphics.Rect;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.TranslateAnimation;
public class BounceBackViewPager extends ViewPager {
private int currentPosition = 0;
private Rect startRect = new Rect();//用来记录初始位置
private static final float RATIO = 0.5f;//摩擦系数
public BounceBackViewPager(Context context) {
super(context);
}
public BounceBackViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
private TouchMoveHelper eventHelper;
@Override
protected void onFinishInflate() {
super.onFinishInflate();
eventHelper = new TouchMoveHelper(getContext());
eventHelper.setTouchEventAdapter(new TouchMoveHelper.TouchEventAdapter() {
@Override
public void onTouchDown() {
startRect.set(getLeft(), getTop(), getRight(), getBottom());
currentPosition = getCurrentItem();
}
@Override
public void onTouchUp() {
recoveryPosition();
}
@Override
boolean onTouchMove(float offsetX, float offsetY) {
if (isStartPosition() && offsetX > 0||isEndPosition() && offsetX < 0) {
moveByTouchOffset(offsetX,0);
return true;
}
//如果想拦截竖直方向页可以换下参数即可
// if (isStartPosition() && offsetY > 0||isEndPosition() && offsetY < 0) {
// moveByTouchOffset(0,offsetY);
// return true;
// }
return false;
}
});
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return eventHelper.onInterceptTouchEvent(ev) || super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
return eventHelper.onTouchEvent(ev) || super.onTouchEvent(ev);
}
private boolean isStartPosition() {
return getAdapter().getCount() == 1 || (getAdapter().getCount() != 1 && currentPosition == 0);
}
private boolean isEndPosition() {
return getAdapter().getCount() == 1 || (getAdapter().getCount() != 1 && currentPosition == getAdapter().getCount() - 1);
}
private void moveByTouchOffset(float offsetX,float offsetY) {
layout(getLeft()+(int)(offsetX * RATIO), getTop() + (int)(offsetY * RATIO), getRight()+(int)(offsetX * RATIO), getBottom() + (int)(offsetY * RATIO));
}
private void recoveryPosition() {
TranslateAnimation ta = new TranslateAnimation(getLeft(), startRect.left, getTop(), startRect.top);
ta.setDuration(300);
startAnimation(ta);
layout(startRect.left, startRect.top, startRect.right, startRect.bottom);
startRect.setEmpty();
}
}
其实就是网上找的代码,为了好理解重构了下。