Android之MotionEvent学习



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);
        }
    }

测试结果:

时间: 2024-10-05 07:03:31

Android之MotionEvent学习的相关文章

Android自定义View学习笔记04

Android自定义View学习笔记04 好长时间没有写相关的博客了,前几周在帮学姐做毕设,所以博客方面有些耽误.过程中写了一个类似wp的磁贴的view,想再写个配套的layout,所以昨天看了一下自定义viewGroup的相关知识-晚上睡觉想了一下可行性不是很高-代码量还不如直接自己在xml上写来得快,速度上也是个问题.今天看了一下张鸿洋老师的Android 自定义View (三) 圆环交替 等待效果这篇博文,再加上前一段时间看到的一幅图,结合之前写的一个圆形imageView的实现博文And

android 浮动窗口学习笔记及个人理解(仿360手机助手)

非常感谢原文作者 http://blog.csdn.net/guolin_blog/article/details/8689140 经自己理解 程序运行界面如下图: 1.程序入口界面 2.小浮动窗口 3.大浮动窗口 由上图可看出,可以看出我们基本需要: 1.一个主Activity 2.小浮动窗口view界面 3.大浮动窗口view界面 对于浮动窗口的管理我们还需要 4.一个Service(在后台监控管理浮动窗口的状态) 5.窗口管理类(创建/消除浮动窗口) 代码: package com.ww.

基于 Android NDK 的学习之旅----- C调用Java

http://www.cnblogs.com/luxiaofeng54/archive/2011/08/17/2142000.html 基于 Android NDK 的学习之旅----- C调用Java许多成熟的C引擎要移植到Android 平台上使用 , 一般都会 提供 一些接口, 让Android sdk 和 jdk 实现. 下文将会介绍 C 如何 通过 JNI 层调用 Java 的静态和非静态方法. 1.主要流程 1.  新建一个测试类TestProvider.java a)       

【转】基于 Android NDK 的学习之旅-----数据传输(引用数据类型)

原文网址:http://www.cnblogs.com/luxiaofeng54/archive/2011/08/20/2147086.html 基于 Android NDK 的学习之旅-----数据传输二(引用数据类型)(附源码) 基于 Android NDK 的学习之旅-----数据传输(引用数据类型) 接着上篇文章继续讲.主要关于引用类型的数据传输,本文将介绍字符串传输和自定义对象的传输. 1.主要流程 1.  String 字符串传输 a)         上层定义一个native的方法

Android Web Service学习总结(一)

最近学习android平台调用webWebService,学习了一篇不错的博客(http://blog.csdn.net/lyq8479/article/details/6428288),可惜是2011年时的方法,而不适合现在android4.0之后的android版本,所以通过一番学习和研究,总结如下. web Service简介 通俗的理解:通过使用WebService,我们能够像调用本地方法一样去调用远程服务器上的方法.我们并不需要关心远程的那个方法是Java写的,还是PHP或C#写的:我

Android ARM指令学习

在逆向分析Android APK的时候,往往需要分析它的.so文件.这个.so文件就是Linux的动态链接库,只不过是在ARM-cpu下编译的.所以学习Android下的ARM指令很重要.目前,市面上的ARM-cpu基本都支持一种叫做THUMB的指令集模式.这个THUMB指令集可以看作是ARM指令集的子集,只不过ARM指令集为32bit,THUMB指令集为16bit.之所以要使用这个THUMB指令集,主要是为了提升代码密度.具体信息大家可以google. 下面介绍如何简单修改.so文件. 首先,

Android热修复学习之旅——HotFix完全解析

在上一篇博客Android热修复学习之旅开篇--热修复概述中,简单介绍了各个热修复框架的原理,本篇博客我将详细分析QQ空间热修复方案. Android dex分包原理介绍 QQ空间热修复方案基于Android dex分包基础之上,简单概述android dex分包的原理就是:就是把多个dex文件塞入到app的classloader之中,但是android dex拆包方案中的类是没有重复的,如果classes.dex和classes1.dex中有重复的类,当classes.dex和classes1

android开发的学习路线

android开发的学习路线 第一阶段:Java面向对象编程1.Java基本数据类型与表达 式,分支循环. 2.String和StringBuffer的使用.正则表达式. 3.面向对象的抽象,封装,继承,多态,类与对象,对象初始化和回 收:构造函数.this关键字.方法和方法的参数传递过程.static关键字.内部类,Java的垃极回收机制,Javadoc介绍. 4.对象实例化 过程.方法的覆盖.final关键字.抽象类.接口.继承的优点和缺点剖析:对象的多态性:子类和父类之间的转换.抽象类和接

Android Afinal框架学习(一) FinalDb 数据库操作

框架地址:https://github.com/yangfuhai/afinal 对应源码: net.tsz.afinal.annotation.sqlite.* net.tsz.afinal.db.sqlite.* net.tsz.afinal.db.table.* net.tsz.afinal.utils.ClassUtils.net.tsz.afinal.utils.FieldUtils FinalDb 建库 FinalDb db = FinalDb.create(context, "my