getAction()方法返回的是int类型,用到的只有低16位(0x0000),其中:低八位是动作的类型,高8位是触摸点索引值的表示
1、如果mAction的值是0x0000,则表示是第一个触控点的ACTION_DOWN操作。
如果mAction的值是0x0100,则表示是第二个触控点的ACTION_DOWN操作。
第三个的ACTION_DOWN呢?相信你可以推出来是0x0200。
总而言之,mAction时的低8位(也就是0-7位)是动作类型信息。
mAction的8-15位呢,是触控点的索引信息。(即表示是哪一个触控点的事件)。
2、应用
1)获得动作类型: int action = event.getAction() & ACTION_MASK
或者使用 getActionMasked()
2)获得触摸点索引类型: int pointerIndex = (event.getAction() & ACTION_POINTER_INDEX_MASK
) >> ACTION_POINTER_INDEX_SHIFT
或者使用 getActionIndex()
3)getAction()与getActionMasked()区别
/** * Bit mask of the parts of the action code that are the action itself. */ public static final int ACTION_MASK = 0xff; /** * Return the kind of action being performed. * Consider using {@link #getActionMasked} and {@link #getActionIndex} to retrieve * the separate masked action and pointer index. * @return The action, such as {@link #ACTION_DOWN} or * the combination of {@link #ACTION_POINTER_DOWN} with a shifted pointer index. */ public final int getAction() { return nativeGetAction(mNativePtr); } /** * Return the masked action being performed, without pointer index information. * Use {@link #getActionIndex} to return the index associated with pointer actions. * @return The action, such as {@link #ACTION_DOWN} or {@link #ACTION_POINTER_DOWN}. */ public final int getActionMasked() { return nativeGetAction(mNativePtr) & ACTION_MASK; }
4)getActionIndex()源码:
/** * For {@link #ACTION_POINTER_DOWN} or {@link #ACTION_POINTER_UP} * as returned by {@link #getActionMasked}, this returns the associated * pointer index. * The index may be used with {@link #getPointerId(int)}, * {@link #getX(int)}, {@link #getY(int)}, {@link #getPressure(int)}, * and {@link #getSize(int)} to get information about the pointer that has * gone down or up. * @return The index associated with the action. */ public final int getActionIndex() { return (nativeGetAction(mNativePtr) & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT; }
其中ACTION_POINTER_INDEX_MASK,ACTION_POINTER_INDEX_SHIFT分别为:
/** * Bits in the action code that represent a pointer index, used with * {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}. Shifting * down by {@link #ACTION_POINTER_INDEX_SHIFT} provides the actual pointer * index where the data for the pointer going up or down can be found; you can * get its identifier with {@link #getPointerId(int)} and the actual * data with {@link #getX(int)} etc. */ public static final int ACTION_POINTER_INDEX_MASK = 0xff00; /** * Bit shift for the action bits holding the pointer index as * defined by {@link #ACTION_POINTER_INDEX_MASK}. */ public static final int ACTION_POINTER_INDEX_SHIFT = 8;
5)getAction()常用动作:
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;
6)判断是否为多点触控:event.getPointerCount() > 1
/* The number of pointers of data contained in this event. Always >= 1.*/ public final int getPointerCount() { return nativeGetPointerCount(mNativePtr); }
7)获得触摸事件的X,Y坐标
float x = event.getXPrecision()*event.getX()+event.getX(); float y = event.getYPrecision()*event.getY()+event.getY();
单击事件采用getX(),getY();多点触摸事件采用getX(int pointerIndex),getY(int pointerIndex),pointerIndex为多点触摸的指针索引
I . getX(),getY()源码:
/*{@link #getX(int)} for the first pointer index (may be an arbitrary pointer identifier).*/ public final float getX() { return nativeGetAxisValue(mNativePtr, AXIS_X, 0, HISTORY_CURRENT); } public final float getY() { return nativeGetAxisValue(mNativePtr, AXIS_Y, 0, HISTORY_CURRENT); }
II . getX(int),getY(int)源码:
/** * Returns the X coordinate of this event for the given pointer * <em>index</em> (use {@link #getPointerId(int)} to find the pointer * identifier for this index). * Whole numbers are pixels; the * value may have a fraction for input devices that are sub-pixel precise. * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0 * (the first pointer that is down) to {@link #getPointerCount()}-1. */ public final float getX(int pointerIndex) { return nativeGetAxisValue(mNativePtr, AXIS_X, pointerIndex, HISTORY_CURRENT); } public final float getY(int pointerIndex) { return nativeGetAxisValue(mNativePtr, AXIS_Y, pointerIndex, HISTORY_CURRENT); }
III . getXPrecision(),getYPrecision()源码:
/** * Return the precision of the X coordinates being reported. You can * multiply this number with {@link #getX} to find the actual hardware * value of the X coordinate. * @return Returns the precision of X coordinates being reported. */ public final float getXPrecision() { return nativeGetXPrecision(mNativePtr); } public final float getYPrecision() { return nativeGetYPrecision(mNativePtr); }
8)MotionEvent的getX(),getY()与getRawX(),getRawY()区别
getRawX()和getRawY()获得的是相对屏幕的位置,getX()和getY()获得的永远是相对view的触摸位置坐标(这两个值不会超过view的长度和宽度)。
RawX,RawY 相对于屏幕位置坐标
X,Y 相对于容器的位置坐标
getRawX()获取的是屏幕上的原生(original raw)x坐标,而getX(int pointerIndex)只是说获取的是指定的触控点坐标,getX()就是获取第一个触控点的坐标。所以, getRawX()就是说,获取的是相对于屏幕左上角的x坐标,而getX()是获取相对控件左上角的x坐标。
/** * Returns the original raw X coordinate of this event. For touch * events on the screen, this is the original location of the event * on the screen, before it had been adjusted for the containing window * and views. */ public final float getRawX() { return nativeGetRawAxisValue(mNativePtr, AXIS_X, 0, HISTORY_CURRENT); } public final float getRawY() { return nativeGetRawAxisValue(mNativePtr, AXIS_Y, 0, HISTORY_CURRENT); }
9)应用实例:
@Override public boolean onTouchEvent(MotionEvent event) { int action = event.getActionMasked(); switch (action) { //单点触控 case MotionEvent.ACTION_DOWN: Toast.makeText(this, "ACTION_DOWN", Toast.LENGTH_SHORT).show(); Log.e("ACTION_DOWN", "*****************************************************"); Log.w("ACTION_DOWN", "getAction : " + event.getAction()); Log.i("ACTION_DOWN", "getActionMasked: " + event.getActionMasked()); float posX = event.getX(); float posY = event.getY(); Log.i("ACTION_DOWN", "getX :: (" + posX + "," + posY + ")"); posX = event.getXPrecision(); posY = event.getYPrecision(); Log.i("ACTION_DOWN", "getPrecision:: (" + posX + "," + posY + ")"); posX = event.getXPrecision() * event.getX() + event.getX(); posY = event.getYPrecision() * event.getY() + event.getY(); Log.i("ACTION_DOWN", "getTotal :: (" + posX + "," + posY + ")"); posX = event.getRawX(); posY = event.getRawY(); Log.i("ACTION_DOWN", "getRaw :: (" + posX + "," + posY + ")"); return true; //多点触控 case MotionEvent.ACTION_POINTER_DOWN: Toast.makeText(this, "ACTION_POINTER_DOWN", Toast.LENGTH_SHORT).show(); Log.e("ACTION_POINTER_DOWN", "*****************************************************"); Log.i("ACTION_POINTER_DOWN", "getPointerCount: " + event.getPointerCount()); Log.w("ACTION_POINTER_DOWN", "getAction : " + event.getAction()); Log.i("ACTION_POINTER_DOWN", "getActionMasked: " + event.getActionMasked()); Log.i("ACTION_POINTER_DOWN", "getActionIndex : " + event.getActionIndex()); Log.i("ACTION_POINTER_DOWN", "getActionId : " + (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)); Log.w("ACTION_POINTER_DOWN", "getPointerId : " + event.getPointerId(event.getActionIndex())); Log.w("ACTION_POINTER_DOWN", "------------------------------------------------------"); float posX0 = event.getX(0); float posX1 = event.getX(1); float posY0 = event.getY(0); float posY1 = event.getY(1); Log.i("ACTION_POINTER_DOWN", "Pointer1:: (" + posX0 + "," + posY0 + ")"); Log.i("ACTION_POINTER_DOWN", "Pointer2:: (" + posX1 + "," + posY1 + ")"); return true; default: return super.onTouchEvent(event); } }
测试结果: