Android触控基础:MotionEvent

来源:互联网 发布:淘宝怎么查快递到哪了 编辑:程序博客网 时间:2024/06/06 01:54

之前的文章层从Framework层介绍了Android Touch事件即(MotionEvent)的传递机制。本文将详细介绍MotionEvent的一些成员和方法。了解了MotionEvent对开发一些特效如拖动控件或多点缩放控件有很大的作用。同时,掌握MotionEvent类也是学好android触控技术的基础。

一、一些常量

常见的动作常量:

    public static final int ACTION_DOWN             = 0;单点触摸动作

    public static final int ACTION_UP               = 1;单点触摸离开动作
    public static final int ACTION_MOVE             = 2;触摸点移动动作
    public static final int ACTION_CANCEL           = 3;触摸动作取消
     public static final int ACTION_OUTSIDE          = 4;触摸动作超出边界
    public static final int ACTION_POINTER_DOWN     = 5;多点触摸动作
    public static final int ACTION_POINTER_UP       = 6;多点离开动作
   以下是一些非touch事件
    public static final int ACTION_HOVER_MOVE       = 7;
    public static final int ACTION_SCROLL           = 8;
    public static final int ACTION_HOVER_ENTER      = 9;
    public static final int ACTION_HOVER_EXIT       = 10;

掩码常量

ACTION_MASK = 0X000000ff动作掩码
 ACTION_POINTER_INDEX_MASK = 0X0000ff00触摸点索引掩码

ACTION_POINTER_INDEX_SHIFT = 8 获取触摸点索引需要移动的位数


二、相关方法

getAction()方法返回的是int类型,用到的只有低16位,其中:低八位是动作的类型,高8位是触摸点索引值的表示(单点为0,双点为1)

获得动作类型: int action = event.getAction() & ACTION_MASK 或者使用 getActionMasked()

获得触摸点索引类型: int pointerIndex = (event.getAction() & ACTION_POINTER_INDEX_MASK ) >> ACTION_POINTER_INDEX_SHIFT 

或者使用 getActionIndex()

为什么要有索引信息?

有了索引信息,我们可以在onTOuchEvent事件中判断传进来的MotionEvent对象对应的是单点信息还是多点信息。

下面的代码段能使用户在屏幕上拖动一个对象。它记录了初始点的位置,计算点移动的距离,并将对象移动到新的位置。它正确的处理了这种情况:当第一个手指把控件拖到一个位置,然后按下第二个手指,且第二个手指与同一个控件上。当用户抬起第一个手指时,控件不会跑到第二个手指的位置同时第二个手指可以继续拖动控件。

// The ‘active pointer’ is the one currently moving our object.private int mActivePointerId = INVALID_POINTER_ID;@Overridepublic boolean onTouchEvent(MotionEvent ev) {    // Let the ScaleGestureDetector inspect all events.    mScaleDetector.onTouchEvent(ev);                 final int action = MotionEventCompat.getActionMasked(ev);             switch (action) {     case MotionEvent.ACTION_DOWN: {        final int pointerIndex = MotionEventCompat.getActionIndex(ev);         final float x = MotionEventCompat.getX(ev, pointerIndex);         final float y = MotionEventCompat.getY(ev, pointerIndex);                     // Remember where we started (for dragging)        mLastTouchX = x;        mLastTouchY = y;        // Save the ID of this pointer (for dragging)        mActivePointerId = MotionEventCompat.getPointerId(ev, 0);        break;    }                case MotionEvent.ACTION_MOVE: {        // Find the index of the active pointer and fetch its position        final int pointerIndex =                 MotionEventCompat.findPointerIndex(ev, mActivePointerId);                      final float x = MotionEventCompat.getX(ev, pointerIndex);        final float y = MotionEventCompat.getY(ev, pointerIndex);                    // Only move if the ScaleGestureDetector isn't processing a gesture.        if (!mScaleDetector.isInProgress()) {            // Calculate the distance moved            final float dx = x - mLastTouchX;            final float dy = y - mLastTouchY;            mPosX += dx;            mPosY += dy;            invalidate();        }        // Remember this touch position for the next move event        mLastTouchX = x;        mLastTouchY = y;        break;    }                case MotionEvent.ACTION_UP: {        mActivePointerId = INVALID_POINTER_ID;        break;    }                case MotionEvent.ACTION_CANCEL: {        mActivePointerId = INVALID_POINTER_ID;        break;    }            case MotionEvent.ACTION_POINTER_UP: {                    final int pointerIndex = MotionEventCompat.getActionIndex(ev);         final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);         if (pointerId == mActivePointerId) {            // This was our active pointer going up. Choose a new            // active pointer and adjust accordingly.            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;            mLastTouchX = MotionEventCompat.getX(ev, newPointerIndex);             mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex);             mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);        }        break;    }    }           return true;}

MotionEvent还包含了移动操作中其它历史移动数据以方便处理触控的移动操作.

android sdk对于这个类的描述中就有这么一句:

For efficiency, motion events with ACTION_MOVE may batch together multiple movement samples within a single object.



16 0