zoukankan      html  css  js  c++  java
  • 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.
         */
        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);
     }
  • 相关阅读:
    P4127 [AHOI2009]同类分布
    区间DP
    P3146 [USACO16OPEN]248
    P1241 括号序列
    P2858 [USACO06FEB]奶牛零食Treats for the Cows
    P2602 [ZJOI2010]数字计数&P1239 计数器&P4999 烦人的数学作业
    数位DP
    jquery生成元素注册事件无效,及事件委托的使用
    Jquery ajax运用执行顺序有误怎么解决
    html页面输入框input的美化
  • 原文地址:https://www.cnblogs.com/xilinch/p/2682028.html
Copyright © 2011-2022 走看看