我们经常在dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent中看到MotionEvent对象,通过这个对象我可以可以获取触摸事件然后进行相应的操作,触摸事件类型比较常用的就是ACTION_UP、ACTION_DOWN、ACTION_MOVE等。获取触摸点坐标有以下方法
getX() 获取触摸点X轴坐标
getY() 获取触摸点Y轴坐标
getX(int pointerIndex)、getY(int pointerIndex) 在多点触控时获取对应手指的坐标
getRawX()、getRawY() 与getX()、getY()的区别是前者相对手机屏幕,后者相对当前控件
在获取MotionEvent的Action事件的时候,我们看到以下两个方法可以获取当前的事件:
getAction():
getActionMasked():
两个方法的区别在于,getActionMasked方法中多了一个&ACTION_MASK:
public static final int ACTION_MASK = 0xff;
我们把nativeGetAction(mNativePtr)比作mActionValue也就是说mActionValue & 0xff表示只要mActionValue的值在0x00-0xff之间的话,getAction与getActionMasked返回值是一样的,因为ff是十六进制转换成2进制就是11111111 与它相与的数只要小于等于它都是原值,&(与)可以用作位运算符,例如1101 & 1011 = 1001,按位进行比较两个都为1则为1,否则为0。
那什么时候两个方法返回的不一样呢?
肯定是返回的值大于0xff的时候。
那又是什么时候返回的值大于0xff呢?
答案就是多点触控的时候。
因为既然是多点触控,如果我们要获取某一点的触控信息怎么获取,肯定需要有一个索引,android就把索引的信息放在action高八位中存储,也就是说0x00-0xff代表的是当前触摸时间的类型,存放在action低八位中.一个字段存放两种信息.所以0xff=0x00ff,00代表高八位存储索引信息,ff代表事件类型,由此推论getAction()返回触摸事件类型,如果是多点触控则返回ACTION_POINTER_DOWN与索引信息的混合值,而getActionMasked()由于 & 0xff(0x00ff)的操作,清空了索引信息,只返回ACTION_POINTER_DOWN的值,如果想单独获取索引信息的话可通过getActionIndex()方法。
public static final int ACTION_POINTER_INDEX_MASK = 0xff00;
public static final int ACTION_POINTER_INDEX_SHIFT = 8;
public final int getActionIndex() {
return (nativeGetAction(mNativePtr) & ACTION_POINTER_INDEX_MASK)
>> ACTION_POINTER_INDEX_SHIFT;
}
通过上述代码可得知mActionValue & ACTION_POINTER_INDEX_MASK(0xff00)会清空低八位的值也就是事件类型的值,只留下索引信息的值,再通过>> ACTION_POINTER_INDEX_SHIFT(8) 将值右移八位返回。
关于高八位与低八位的一些解释:
一般来说内存操作都是针对内存,也就是一个字节,8位。如果是16位的指令,就是同时操作连续的2个内存地址,将这连续的2个内存地址当成一个单位,所有就有高8位和低8位之分。由于计算机仅识别二进制,所以对一个内存地址,也就是8位二进制,如:0000 0001 0000就是高四位,0001就是低四位,当然2个内存地址,就是16位二进制,也就是:0000 0001 0000 0002,0000 0001 就是高八位,0000 0002就是低八位