android单点、多点触控之MotionEvent

最近学习android开始接触到屏幕触摸控制这部分的内容,通过描述自己的遇到的小问题和理解、解决的整个过程来讲解一下MotionEvent在单点和多点触控下的区别。

在进行屏幕触摸onTouch(View v, MotionEvent event)操作的过程中,参数中的view代表触摸的视图,说白了就是你正在触摸的控件,这个参数没什么特别和复杂之处;MotionEvent参数存储的是触摸时的整个触摸动作:对屏幕进行了什么动作(按下、移动或者释放),还有屏幕上同时触摸点的个数和各个同时触摸点的索引和id。

单点触控:单点触控中,主要注重的是对屏幕进行的动作,因为只有一个触摸点,不需要去理会触摸点个数和索引、id这些较为复杂的属性。所以单点触控的代码很简单:

 1 public boolean onTouch(View v, MotionEvent event) {
 2         switch (event.getAction()) {
 3         case MotionEvent.ACTION_DOWN:
 4             //do someting during finger down
 5             break;
 6         case MotionEvent.ACTION_MOVE:
 7             //do someting during finger move
 8             break;
 9         case MotionEvent.ACTION_CANCEL:
10             //do someting during finger cancel
11             break;
12         case MotionEvent.ACTION_UP:
13             //do someting during finger cancel
14             break;
15         }

这段代码虽然理解起来很简单,但是关于MotionEvent的“能力”可并非只有这么点。

我们知道,现在的android手机都支持多点触控了(5以后的android设备基本都支持),这个功能方便了我们很多页面缩放等操作,也使我们的手机游戏从最初的益智游戏发展到现在界面炫丽操作性强的Rpg和3D游戏,那么MotionEvent是如何识别和解析我们的多个手指的呢?

是这样的,MotionEvent中存入的是一个整形的值,在单点触控的时候,它有8位的有效二进制值,这8位的二进制值分别对应ACTION_DOWN、ACTION_MOVE等动作;而在多点触控的过程中,它会增加高8位的有效值,这八位值里边存储的则是每个手指对应的索引值,通过这个索引值我们可以获取每个手指的ID值来唯一识别每个触控点。

那么怎么来得到这个索引值,又如何通过索引值获取ID呢?这里需要引入两个常量和一个方法:MotionEvent.ACTION_POINTER_ID_MASK、MotionEvent.ACTION_POINTER_ID_SHIFT常量和event.getPointerId(pointerIndex)方法。

MotionEvent.ACTION_POINTER_ID_MASK:值为0xff00转换成二进制--->1111 1111 0000 0000(用来与MotionEvent.getAction进行按位AND操作,转换成二进制比较直观);

MotionEvent.ACTION_POINTER_ID_SHIFT:值为0x0008;

event.getPointerId(pointerIndex):这个就不用说了,通过索引获取一个对象的ID,一般的程序员都懂得。

接下来就是如何获取索引了,我们刚说过早MotionEvent.getAction中共存储了16位二进制数,其中高8位是用来存储索引的,也就是我们现在要用到的数据,我们就可以把低八位的数据去掉,将高8位的数据保存下来。操作方法就是先将MotionEvent.getAction跟常量MotionEvent.ACTION_POINTER_ID_MASK按位And,保留高8位的数据,然后将结果右移MotionEvent.ACTION_POINTER_ID_SHIFT个单位,杀掉低8位的数字。代码如下:

int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;

再获取ID:

int pointerId = event.getPointerId(pointerIndex );

最后,还要将16位的MotionEvent.getAction值取低八位表示action的动作,具体操作是将MotionEvent.getAction与一个常量MotionEvent.ACTION_MASK按位AND,

MotionEvent.ACTION_MASK:值为0x00ff转换成二进制--->0000 0000 1111 1111;

int action = event.getAction() & MotionEvent.ACTION_MASK;

获取到每个触控点的ID号和改触控点的Action(具体的action枚举常量请参见android帮助文档,这里就不一一列举了),就可以控制每个触控点的各个动作了!

原文地址:https://www.cnblogs.com/feiguotianyahaijiao/p/2918297.html