这是我个人的看法,要学好android触控,了解MotionEvent是必要,对所用的MotionEvent常用的API要比较深入的了解.

(1)首先是MotionEvent 中getAction()与getActionMasked()的区别:

首先看代码:

01 /**
02 * Bit mask of the parts of the action code that are the action itself.
03 */
04 publicstaticfinalintACTION_MASK =0xff;
05
06 /**
07 * Return the kind of action being performed.
08 * Consider using {<a href="http://my.oschina.net/link1212" class="referer" target="_blank">@link</a> #getActionMasked} and {<a href="http://my.oschina.net/link1212" class="referer" target="_blank">@link</a> #getActionIndex} to retrieve
09 * the separate masked action and pointer index.
10 * @return The action, such as {<a href="http://my.oschina.net/link1212" class="referer" target="_blank">@link</a> #ACTION_DOWN} or
11 * the combination of {<a href="http://my.oschina.net/link1212" class="referer" target="_blank">@link</a> #ACTION_POINTER_DOWN} with a shifted pointer index.
12 */
13 publicfinalintgetAction() {
14 returnmAction;
15 }
16
17 /**
18 * Return the masked action being performed, without pointer index information.
19 * Use {<a href="http://my.oschina.net/link1212" class="referer" target="_blank">@link</a> #getActionIndex} to return the index associated with pointer actions.
20 * @return The action, such as {<a href="http://my.oschina.net/link1212" class="referer" target="_blank">@link</a> #ACTION_DOWN} or {<a href="http://my.oschina.net/link1212" class="referer" target="_blank">@link</a> #ACTION_POINTER_DOWN}.
21 */
22 publicfinalintgetActionMasked() {
23 returnmAction & ACTION_MASK;
24 }

上面的代码是基于android2.2的,注释是android4.X中最新的.

初看一下从技术角度来说通过getActionMasked()和通过getAction()返回的结果应该是一样的,

因为ACTION_MASK 的值 是0xff,

如果您对二进制位运算不太熟悉的话,请用下面的方法测试吧.看是不是这样的.

1 privatestaticvoidmaskTest() {
2 for(inti =0; i <5; i++) {
3 System.out.println(""+ i);
4 System.out.println("masked "+ (i &0xff));
5 }
6 }

那他们区别是什么呢?先看关于这两个方法注释:

我简单的翻译如下:

01 /**
02 * action码的位掩码部分就是action本身
03 */
04 publicstaticfinalintACTION_MASK =0xff;
05
06 /**
07 返回action的类型,考虑使用getActionMasked()和getActionIndex()来获得单独的经过掩码的action和触控点的索引.
08 @return action例如ACTION_DOWN或者ACTION_POINTER_DOWN与转换的触控点索引的合成值
09 */
10 publicfinalintgetAction() {
11 returnmAction;
12 }
13
14 /**
15 返回经过掩码的action,没有触控点索引信息.
16 通过getActionIndex()来得到触控操作点的索引.
17 @return action,例如ACTION_DOWN,ACTION_POINTER_DOWN
18
19
20 */
21 publicfinalintgetActionMasked() {
22 returnmAction & ACTION_MASK;
23 }

在上面的两个方法中注释出现差异的地方是对于ACTION_POINTER_DOWN的描述:

通过getAction()返回的ACTION_POINTER_DOWN的是与转换触控点索引的合成值.

而getActionMasked()则就是一个ACTION_POINTER_DOWN的值:

这么来看我们知道一个action的代码值还包含了action是那个触控点的索引值:

现在我们对比来看看ACTION_MASK和ACTION_POINTER_INDEX_MASK

1 publicstaticfinalintACTION_MASK =0xff;
2 publicstaticfinalintACTION_POINTER_INDEX_MASK =0xff00;

还没有看出来什么吗?

您把ACTION_MASK看成是0x00ff

就知道了吧.

也就是说,一个MotionEvent中的action代码,

前8位是实实在在包含表示哪一个动作常量.

后八位呢就是包含了触控点的索引信息.

因为ACTION_MASK = 0x00ff所以,经过ACTION_MASK掩码过后的action码就没有索引信息了.

如何得索引值呢?

原理:

先将action跟0xff00相与清除前8位用于存储动作常量的信息,

然后将action右移8位就可以得到索引值了.

我们就可以自己想办法得到索引信息了.

即先对action用ACTION_POINTER_INDEX_MASK进行掩码处理,

即 maskedIndex = action&ACTION_POINTER_INDEX_MASK = action&0xff00

这各掩码也就是将action这个数的前8位清零.

然后再将maskedIndex向右移8位就能够得到索引值了.

再看看android真实是怎么做的吧,

用于右移8位的常量.

1 /**
2 * Bit shift for the action bits holding the pointer index as
3 * defined by {<a href="http://my.oschina.net/link1212" class="referer" target="_blank">@link</a> #ACTION_POINTER_INDEX_MASK}.
4 */
5 publicstaticfinalintACTION_POINTER_INDEX_SHIFT =8;

再年得到索引值方法源代码,如下:

1 publicfinalintgetActionIndex() {
2 return(mAction & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT;
3 }

为什么要有索引信息?

因为,这样说吧,android中,当有触摸事件发生时(假设已经注册了事件监听器),调用你注册监听器中的方法onTouch(,MotionEvent ev);传递了一个MotionEvent的对象过来.

但是,想想,上面只传递进来一个MotionEvent过来,如果只是单点触控那是没有问题.

问题就是当你多个手指触控的时候也是只传递这一个MotionEvent进来,

这个时候,你当然想知道每个手指的所对应的触控点数据信息啦.

所以MotionEvent中有就要索引信息了.

事件是你可以很容易通过API看到,MotionEvent还包含了移动操作中其它历史移动数据.

方便处理触控的移动操作.

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

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

我翻译下:"出于效率的考虑,事件代码为ACTION_MOVE的Motion,会在一个MotionEvent对象中包含多个移动数据采样."

现在我们对于MotionEvent有了初步的了解了.

PS:

我发现android4中MotionEvent中的代码大多变成了原生代码了:

例如如getX(int)在2.2中是这样的:

1 publicfinalfloatgetX(intpointerIndex) {
2 returnmDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_X];
3 }

但到了4.x是这样的了:

1 publicfinalfloatgetX(intpointerIndex) {
2 returnnativeGetAxisValue(mNativePtr, AXIS_X, pointerIndex, HISTORY_CURRENT);
3 }

转载: http://my.oschina.net/banxi/blog/56421

更多相关文章

  1. Android(安卓)Studio第一次启动的Fetching android sdk componen
  2. Android中WebView和JavaScript通信
  3. android ctl属性的实现过程
  4. 屏幕锁知识点
  5. 转:Android实现矩形设置菜单
  6. Android使用ImageView引起Missing contentDescription attribute
  7. Android中使用代码执行shell命令
  8. Android使用ViewPager实现左右滑动效果
  9. Android(安卓)/ iOS 静态代码扫描工具调研

随机推荐

  1. xmlns的作用
  2. Handler+Messagequeue+looper
  3. android 设置特殊字体
  4. Android 使用ViewStub 实现多状态页面切
  5. Android菜鸟的成长笔记——Android Studi
  6. android线程池的封装工具类
  7. Android上传图片到服务器,android-async-h
  8. 动画·界面
  9. android震动器类Vibrator
  10. 按键及其居中