我们知道,Android 将我们的操作大致分为 DOWN - MOVE - UP 等几个事件,然而我们在实际中会发现,只要手机接触到屏幕,就会触发 MOVE 事件(因为我们的手指总是不自主的会抖动,而这种细小的抖动,也会被系统检测到),那么问题来了:究竟多长距离的 MOVE 才算是“手指滑动”,而不是“手指抖动”呢?
Android 提供了一个常量:TouchSlop,这常量被认为是滑动事件的“临界点”。当然,各个手机厂家修改后的系统,该“临界点”也会有不同。
我们可以通过如下方法获取到该常量:
int touchSlop = ViewConfiguration.get(this).getScaledTouchSlop();
关于 ViewConfiguration 的其他使用请看这里:Android ViewConfiguration配置说明
有了参照值,我们需要的就是获取我们手指的移动距离了。
MotionEvent 提供了 getX、getY、getRawX 和 getRawY 四个方法来获取我们手指的位置:
相对于 View:
相对于屏幕
他们获取的值的单位都是像素。
View 也提供了一些关于位置的方法:
getTop():View 自身的顶边到其父布局顶边的距离
getLeft():View 自身的左边到其父布局左边的距离
getRight():View 自身的右边到其父布局左边的距离
getBottom():View 自身底边到其父布局顶边的距离
看图:
这样一来,我们就可以判断我们的触摸是否可以触发“滑动”常量了。
有时候我们需要多个手指操作屏幕,例如缩放。
为了表示多点触摸,MotionEvent 引入了一个 Pointer 的概念,每个触摸点都是一个 Pointer,每个 Pointer 都有自己的坐标、事件类型。
一个 MotionEvent 对象可以包含多个 Pointer,每个 Pointer 都有自己的 id 和 index。我们通过 event.getActionIndex()
方法来获取 Pointer 的 index,通过 event.findPointerIndex(actionIndex)
来获取 Pointer 的 id。需要注意的是,Pointer 的不同的 MotionEvent 当中的 index 不同的,但 id 却是不会变化的。
那么问题又随之而来,我们如何判断我们的事件是哪个 Pointer 呢?
除了 Pointer 的概念,MotionEvent 还引入了两个事件类型:
ACTION_POINTER_DOWN:表示用户又有一根手指触摸到了屏幕