原文链接:http://www.jianshu.com/p/5aeaff6f92a7
5种手势工具类
1.ViewConfiguration-视图标准类
1.1.对象方法
ViewConfiguration viewConfiguration=ViewConfiguration.get(context);
//获取touchSlop。该值表示系统所能识别出的被认为是滑动的最小距离
int touchSlop = viewConfiguration.getScaledTouchSlop();
//获取Fling速度的最小值和最大值
int minimumVelocity = viewConfiguration.getScaledMinimumFlingVelocity();
int maximumVelocity = viewConfiguration.getScaledMaximumFlingVelocity();
//判断是否有物理按键boolean isHavePermanentMenuKey=viewConfiguration.hasPermanentMenuKey();
1.2.静态方法
//双击间隔时间.在该时间内是双击,否则是单击
int doubleTapTimeout=ViewConfiguration.getDoubleTapTimeout();
//按住状态转变为长按状态需要的时间
int longPressTimeout=ViewConfiguration.getLongPressTimeout();
//重复按键的时间
int keyRepeatTimeout=ViewConfiguration.getKeyRepeatTimeout();
2.GestureDetector-手势检测器
2.1.创建GestureDetector的实例
public GestureDetectorView(Context context, AttributeSet attrs) {
super(context, attrs);
mGestureDetector = new GestureDetector(context, new GestureListenerImpl());
setLongClickable(true);
}
2.2.实现OnGestureListener接口
private class GestureListenerImpl implements GestureDetector.OnGestureListener {
//按下
@Override
public boolean onDown(MotionEvent motionEvent) {
return false;
}
//按下,与onDown()的区别是:强调的是没有松开或者拖动的状态
@Override
public void onShowPress(MotionEvent motionEvent) {
}
//单击
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
return false;
}
//长按
@Override
public void onLongPress(MotionEvent motionEvent) {
}
//滚动,松手之前
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
return false;
}
//抛出,松手之后
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
return false;
}
}
2.3.将Touch事件交给GestureDetector处理
@Override
public boolean onTouchEvent(MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
特别提醒:
- 默认情况下,onFling()等事件不会被捕捉到。
可以view.setLongClickable(true);
只有这样,view才能够处理不同于Tap(轻触)的hold(即ACTION_MOVE,或者多个ACTION_DOWN)- onScoll是在滑动的时候触发的,onFling是在手指放开的瞬间发生的
3.VelocityTraker-速度追踪器
3.1.开始速度追踪
private void startTracker(MotionEvent event) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
}
3.2.获取追踪到的速度
public int getVelocity() {
// 设置VelocityTracker单位.1000表示1秒时间内运动的像素
mVelocityTracker.computeCurrentVelocity(1000);
// 获取在1秒内X方向所滑动像素值
int xVelocity = (int) mVelocityTracker.getXVelocity();
return Math.abs(xVelocity);
}
3.3.解除速度追踪
private void endTracker() {
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}
4.Scroller-滚动辅助类
1.创建Scroller的实例
mScroller = new Scroller(context);
2.调用startScroll()并刷新
mScroller.startScroll(getScrollX(), getScrollY(), endX, endY);
invalidate();
3.重写computeScroll()并刷新
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
invalidate();
}
}
特别提醒:
- Scroller仅仅只是滚动的计算器,本身并不涉及UI,必须和computeScroll一起狼狈为奸
- 每一次invalidate都会回调一次computeScroll
- scrollTo(x,y)中的x和y,不会改变控件本身的位置,而是改变控件显示内容的位置。与View的视图坐标系相反。口诀:左上为正
5.ViewDragHelper-拖动辅助类
和GestureDetector的用法类似。
5.1.创建ViewDragHelper的实例
mDragHelper = ViewDragHelper.create(this, 1.0f, new CallbackImpl());
5.2.实现Callback接口
private class CallbackImpl extends ViewDragHelper.Callback {
//是否捕获,为true则捕获
@Override
public boolean tryCaptureView(View child, int pointerId) {
return false;
}
//设置水平位移
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
return super.clampViewPositionHorizontal(child, left, dx);
}
//设置竖直位移
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
return super.clampViewPositionVertical(child, top, dy);
}
//位置改变
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
super.onViewPositionChanged(changedView, left, top, dx, dy);
}
//状态改变
@Override
public void onViewDragStateChanged(int state) {
super.onViewDragStateChanged(state);
}
//放开
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
super.onViewReleased(releasedChild, xvel, yvel);
}
}
5.3.将Touch事件交给ViewDragHelper处理
@Override
public boolean onInterceptTouchEvent(android.view.MotionEvent ev) {
return mDragHelper.shouldInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mDragHelper.processTouchEvent(event);
return true;
}
特别提醒:
- 创建时传入的1.0f是敏感度参数(也可不传,默认为1),参数越大越敏感。第一个参数为this,表示该类生成的对象,他是ViewDragHelper的拖动处理对象,必须为ViewGroup。
- 需要边缘拖拽时,可以在创建ViewDragHelper实例时设置mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT),然后监听onEdgeDragStarted()
- 子View带有clickable属性时,可将getViewHorizontalDragRange()和getViewVerticalDragRange()返回1