Android多点触控基础
处理多点触控手势
多点触控就是同时把一根以上的手指放在屏幕上。
再继续往下以前需要补充一些名词(弄清楚这些对理解下面的内容非常有用):
- 触控手势:就是把一根或者几根手指放在屏幕上做各种动作,在保留一根手指的前提下,移动、拿起或者放下其余的手指。
- 触控事件:在触控手势中,有手指移动或者离开屏幕的时候就会引发一系列的触控事件。每引发一个事件就会出现一个
MotionEvent。在这个事件中,包含说与的触控数据。 - 触控:手指碰到屏幕的时候就产生了一个触控(pointer)。
一个触控手势包含一个或多个触控事件。一个触控事件包含一个或多个触控。比如用两个手指敲击屏幕,会有一个MotionEvent.ACTION_DOWN一个MotionEvent.ACTION_POINTER_DOWN,点击用力的话还会连续多个的MotionEvent.ACTION_MOVE,最后出现MotionEvent.ACTION_UP和MotionEvent.ACTION_POINTER_UP。那么,“两个手指敲击屏幕”就是一个触控手势,顺序依次出现的多个MotionEvent就是触控事件,每个触控事件可以通过getActionIndex方法获得一个触控点(Pointer)。
追踪多个触控点
多个手指同时放在屏幕上的时候会触发以下的系统事件:
* ACTION_DOWN –第一个对屏幕的触碰。这是多点触控的开始。这个触碰的而数据保存在index为0的MotionEvent中。
* ACTION_POINTER_DOWN–其他对屏幕的触碰。触碰事件的index可以用方法getActionIndex()获取到。触碰的数据保存在这个index指定的MotionEvent中。
* ACTION_MOVE–放在屏幕上的任何一根手指移动的时候触发。
* ACTION_POINTER_UP–第一个触摸屏幕的手指以外的其他手指离开屏幕的时候触发。
* ACTION_UP–当最后一根手指离开屏幕的时候触发。
你可以通过触碰事件的index或者ID来获得事件MotionEvent。
* Index: 一个MotionEvent存储了几根手指触摸屏幕的每一个手指的触碰数据。一般处理触摸的是后都用index作为获取MotionEvent的依据,而不是触碰ID。
* ID:整个多点触摸事件过程中,每一个触摸都有一个ID和整个触摸匹配。
一个触碰的index在MotionEvent中可能发生改变的。而整个触碰的ID是保持不变的,只要整个触碰保持激活状态。用getPointerId()可以获取整个手势执行期间的每一个event里的触碰数据。也可以通过findPointerIndex()来根据一个触控的ID来获取这触控在触控事件中的index。比如:
var mActivePointerId: Int? = nulloverride fun onTouchEvent(event: MotionEvent?): Boolean {mActivePointerId = event?.getPointerId(0)// 其他的事件先不管...// 用触控ID获得index,然后获取位置数据var pointerIndex = event?.findPointerIndex(mActivePointerId!!)// 获取触控的当前位置var x = event?.getX(pointerIndex!!)var y = event?.getY(pointerIndex!!)return true
}
获取一个MotionEvent的Action
你应该使用getActionMasked()(或者从兼容方面考虑的话用MotionEventCompat.getAtionMasked()来获取MotionEvent的action。与getAction()不同,getActionMasked()就是被用来处理多点触控的。这个方法的返回值不在包含触控index的位数。你可以用getActonIndex()来获取触控action的index。这些在后面详细叙述。
注意:后面的例子用的是MotionEventCompat类。这个类在Support Library中。
你可以使用MotionEventCompat来获得更多的平台支持。MotionEventCompat不是用来代替MotionEvent的。
其实,这个类只是提供了一些静态方法以方便使用。
override fun onTouchEvent(event: MotionEvent?): Boolean {var action = MotionEventCompat.getActionMasked(event!!)var index: Int = MotionEventCompat.getActionIndex(event!!)var xPos = -1.0fvar yPos = -1.0fLog.d(TAG, "The action is " + actionToSring(action))if (event!!.pointerCount > 1) {Log.d(TAG, "Mutipletouch event")// 坐标系是相对于处理这个事件的View或者Activity的xPos = MotionEventCompat.getX(event!!, index)yPos = MotionEventCompat.getY(event!!, index)} else {//单点触控Log.d(TAG, "Single touch event")xPos = MotionEventCompat.getX(event!!, index)yPos = MotionEventCompat.getY(event!!, index)}return true
}fun actionToSring(action: Int): String {when (action) {MotionEvent.ACTION_DOWN -> return "Down"MotionEvent.ACTION_MOVE -> return "Move"MotionEvent.ACTION_POINTER_DOWN -> return "Pointer down"MotionEvent.ACTION_UP -> return "UP"MotionEvent.ACTION_POINTER_UP -> return "Pointer up"MotionEvent.ACTION_OUTSIDE -> return "Outside"MotionEvent.ACTION_CANCEL -> return "Cancel"}return ""
}
原文是Google的文档。但是文档中的前提和一些概念的描述不足,会导致初学者理解出现偏差。我都加上了,我就是初学者。
代码都是用Kotlin写的,自从用了这个语言就再也不想用Java了。对于Java开发者理解Kotlin的代码没有什么太大的问题,Kotlin的可读性更强一些。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
