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);
    }

特别提醒:

  1. 默认情况下,onFling()等事件不会被捕捉到。 可以view.setLongClickable(true); 只有这样,view才能够处理不同于Tap(轻触)的hold(即ACTION_MOVE,或者多个ACTION_DOWN)
  1. 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();
        }
    }

特别提醒:

  1. Scroller仅仅只是滚动的计算器,本身并不涉及UI,必须和computeScroll一起狼狈为奸
  1. 每一次invalidate都会回调一次computeScroll
  2. 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. 创建时传入的1.0f是敏感度参数(也可不传,默认为1),参数越大越敏感。第一个参数为this,表示该类生成的对象,他是ViewDragHelper的拖动处理对象,必须为ViewGroup。
  1. 需要边缘拖拽时,可以在创建ViewDragHelper实例时设置mDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT),然后监听onEdgeDragStarted()
  2. 子View带有clickable属性时,可将getViewHorizontalDragRange()和getViewVerticalDragRange()返回1

参考目录


  1. 自定义View系列教程01--常用工具介绍
  2. Android笔记:GestureDetector
  3. Android触摸事件onScroll和onFling
  4. Android Scroller完全解析,关于Scroller你所需知道的一切
  5. ViewDragHelper解析
  6. ViewDragHelper详解
  7. Android ViewDragHelper完全解析 自定义ViewGroup神器
  8. Android中滑屏初探--scrollTo 以及 scrollBy方法使用说明
  9. Android群英传笔记—第五章:Android Scroll分析
2016-10-29 13:4317