android触控 MotionEvent (转)

简介: 原文:http://my.oschina.net/banxi/blog/56421 (1)  MotionEvent 中getAction()与getActionMasked()的区别:   /** * Bit mask of the parts of the action code that are the action itself.

 

原文:http://my.oschina.net/banxi/blog/56421

(1)  MotionEvent 中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 {<A class=referer href="http://my.oschina.net/link1212" target=_blank>@link</A>  #getActionMasked} and {<A class=referer href="http://my.oschina.net/link1212" target=_blank>@link</A>  #getActionIndex} to retrieve
     * the separate masked action and pointer index.
     * @return The action, such as {<A class=referer href="http://my.oschina.net/link1212" target=_blank>@link</A>  #ACTION_DOWN} or
     * the combination of {<A class=referer href="http://my.oschina.net/link1212" target=_blank>@link</A>  #ACTION_POINTER_DOWN} with a shifted pointer index.
     */
    public final int getAction() {
        return mAction;
    }

  /**
     * Return the masked action being performed, without pointer index information.
     * Use {<A class=referer href="http://my.oschina.net/link1212" target=_blank>@link</A>  #getActionIndex} to return the index associated with pointer actions.
     * @return The action, such as {<A class=referer href="http://my.oschina.net/link1212" target=_blank>@link</A>  #ACTION_DOWN} or {<A class=referer href="http://my.oschina.net/link1212" target=_blank>@link</A>  #ACTION_POINTER_DOWN}.
     */
    public final int getActionMasked() {
        return mAction & ACTION_MASK;
    }

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

 

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

因为ACTION_MASK 的值 是0xff, 

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

 

 /**
     * action码的位掩码部分就是action本身
     */
    public static final int ACTION_MASK             = 0xff;

/**
  返回action的类型,考虑使用getActionMasked()和getActionIndex()来获得单独的经过掩码的action和触控点的索引.
 @return action例如ACTION_DOWN或者ACTION_POINTER_DOWN与转换的触控点索引的合成值
     */
    public final int getAction() {
        return mAction;
    }

  /**
   返回经过掩码的action,没有触控点索引信息.
   通过getActionIndex()来得到触控操作点的索引.
@return action,例如ACTION_DOWN,ACTION_POINTER_DOWN

 
     */
    public final int getActionMasked() {
        return mAction & ACTION_MASK;
    }

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

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

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

 

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

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

 public static final int ACTION_MASK             = 0xff;
public static final int ACTION_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位的常量.

/**
   * Bit shift for the action bits holding the pointer index as
   * defined by {<A class=referer href="http://my.oschina.net/link1212" target=_blank>@link</A>  #ACTION_POINTER_INDEX_MASK}.
   */
  public static final int ACTION_POINTER_INDEX_SHIFT = 8;

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

public final int getActionIndex() {
    return (mAction & ACTION_POINTER_INDEX_MASK) >> ACTION_POINTER_INDEX_SHIFT;
}

为什么要有索引信息?

 因为,这样说吧,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中是这样的:

public final float getX(int pointerIndex) {
    return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_X];
}

 

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

public final float getX(int pointerIndex) {
     return nativeGetAxisValue(mNativePtr, AXIS_X, pointerIndex, HISTORY_CURRENT);
 }

 

 

 

 

 

 

 

 

 

 

 

 

目录
相关文章
|
Java Android开发
Android Studio入门之按钮触控的解析及实战(附源码 超详细必看)(包括按钮控件、点击和长按事件、禁用与恢复按钮)
Android Studio入门之按钮触控的解析及实战(附源码 超详细必看)(包括按钮控件、点击和长按事件、禁用与恢复按钮)
1134 0
|
Android开发 iOS开发 Windows
无影产品动态|iOS & Android客户端6.0.0版本发布,提升触控灵敏度,操作体验更丝滑
无影ios & Android客户端6.0.0版本发布!移动端触控体验更舒适,用户操作更便捷,一起来看看!
1046 1
无影产品动态|iOS & Android客户端6.0.0版本发布,提升触控灵敏度,操作体验更丝滑
|
9天前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
145 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
|
19天前
|
Java 开发工具 Maven
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
78 6
|
2月前
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
170 11
|
2月前
|
移动开发 Java 编译器
Kotlin与Jetpack Compose:Android开发生态的演进与架构思考
本文从资深Android工程师视角深入分析Kotlin与Jetpack Compose在Android系统中的技术定位。Kotlin通过空安全、协程等特性解决了Java在移动开发中的痛点,成为Android官方首选语言。Jetpack Compose则引入声明式UI范式,通过重组机制实现高效UI更新。两者结合不仅提升开发效率,更为跨平台战略和现代架构模式提供技术基础,代表了Android开发生态的根本性演进。
109 0
|
6月前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
1316 77

热门文章

最新文章