测试单点触摸及多点触摸API
触摸屏是获取用户输入最重要的一种方式。直到Android2.0版本才引入多点触摸。
先测试单点触摸事件,它适用于所有Android版本。我们在视图中注册一个OnTouchListener接口,并把触摸时间传递给这个接口实现。OnTouchListener接口只有一个方法:public abstract boolean onTouch(View v, MotionEvent event)
第一个参数是分派该触摸事件的View,第二个参数是获得触摸事件的参数。
OnTouchListener可在任何View中实现中通过View.setOnTouchListener方法进行注册。在MotionEvent被分派给View本身之前会先调用OnTouchListener方法。我们可在onTouch()方法的实现中返回true通知该View,我们已经处理事件。如果返回为false,那么View将自己处理该事件。
MotionEvent实例包含如下3个我们关心的方法:
MotionEvent.getX()和MotionEvent.getY();这两个方法报告触摸事件相对于View的X和Y坐标。坐标原点位于该视图左上角,X轴指向右边,Y轴指向下。坐标是以像素为单位。该方法返回浮点型数据,因此该坐标具有亚像素精度。
MotionEvent.getAction():返回触摸事件的类型。它是一个整型数,具有如下值之一:MotionEvent.ACTION_DOWN、
MotionEvent.ACTION_MOVE、MotionEvent.ACTION_CANCEL和MotionEvent.ACTION_UP。
顾名思义,当手指触摸屏幕时,将触发MotionEvent.ACTION_DOWN事件。
当手指移动时,则触发MotionEvent.ACTION_MOVE事件。只要手指没有完全脱离屏幕,总可以获得MotionEvent.ACTION_MOVE事件
当手指再次离开屏幕时,MotionEvent.ACTION_UP事件就会触发。
MotionEvent.ACTION_CANCEL事件则稍微神秘。文档说明当前手势取消时会触发该事件,我们还是把它假设为MotionEvent.ACTION_UP事件。
下面是测试代码:
对于处理多点触摸事件就复杂的多,Android2.2版本后对多点触摸做了修改,添加了新的方法和常量,甚至重命名了常量。这些改变可能会让处理多点触摸容易些。不过只支持Android2.2以后的版本,为了支持Android2.0--Android2.21版本,我们使用Android2.0的API。
当处理多点触摸事件时,我们使用重载的方法,它们带有一个所谓的指针索引,如event.getX(pointerIndex);
pointIndex是MotionEvent的内部数组中的一个索引,它包含特定手指触摸屏幕事件的坐标值。而真正识别屏幕上的一根手指是指针ID。指针ID是一个任意数字,可以唯一标识触摸屏幕的一个指针的实例。有一个方法MotionEvent.getPointerIdentifier(int pointerIndex),它返回一个基于指针索引的指针ID。只要手指还触摸在屏幕上,一个指针ID就与一根手指保持相同,而指针索引就不一定这样了。先来看看是如何获取指针索引:
int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
ACTION_POINTER_ID_MASK的常量的值是0xff00,因此低8位为0,高8位为15,用于保存事件的指针索引。
整数的低8位可从event.getAction()方法返回得到,用于保存事件类型的值。我们通过MotionEvent.ACTION_POINTER_ID_SHIFT来移位,该值为8,因此实际上是将第15位移到第8位,第7位移到第0位。注意我们是获取pointerIndex而常量却是XXX_POINTER_ID_XXX而不是XXX_POINTER_INDEX_XXX
获取事件类型,我们只需屏蔽指针索引:
int action = event.getAction() & MotionEvent.ACTION_MASK;
这里我们会遇到新的事件类型,
MotionEvent.ACTION_POINTER_DOWN:除了第一根手指外的任何手指触摸屏幕,都将发生该事件,而第一根手指仍然产生MotionEvent.ACTION_DOWN事件。
MotionEvent.ACTION_POINTER_UP:多根手指触摸屏幕而一根手指离开屏幕时,将发生该事件。最后一根手指离开屏幕将产生MotionEvent.ACTION_UP事件,而该手指不一定是第一个触摸屏幕的手指。为了检查单个MotionEvent中包含几个事件,可使用MotionEvent.getPointerCount()方法,它会告诉我们MotionEvent中包含多少根手指的坐标。然后我们可通过MotionEvent.getX()、
MotionEvent.getY()和MotionEvent.getPointerId()方法来得到指针ID和从指针索引0到MotionEvent.getPointerCount() - 1的坐标值。
测试代码如下: