拖拽与缩放
本节课程讲述,使用onTouchEvent()截获触摸事件后,如何使用触摸手势拖拽、缩放屏幕上的对象。
如果我们的目标版本为3.0或以上,我们可以使用监听内置的拖放(drag-and-drop)事件,拖拽与释放中有更多相关描述。
对于触摸手势来说,一个很常见的操作是在屏幕上拖拽一个对象。接下来的代码段让用户可以拖拽屏幕上的图片。需要注意以下几点:
- 为了防止这种情况发生,我们的app需要区分初始点以及随后任意的触摸点。要做到这一点,它需要追踪章节中提到过的 ACTION_POINTER_DOWN 和 事件。每当第二根手指按下或拿起时,ACTION_POINTER_DOWN 和 事件就会传递给回调函数。
- 当ACTION_POINTER_UP事件发生时,示例程序会移除对该点的索引值的引用,确保操作中的点的ID(the active pointer ID)不会引用已经不在触摸屏上的触摸点。这种情况下,app会选择另一个触摸点来作为操作中(active)的点,并保存它当前的x、y值。由于在事件时,这个保存的位置会被用来计算屏幕上的对象将要移动的距离,所以app会始终根据正确的触摸点来计算移动的距离。
需要注意的是,代码段中使用了getActionMasked()函数。我们应该始终使用这个函数(或者最好用这个兼容版本)来获得MotionEvent对应的动作(action)。不像旧的函数,getActionMasked()
就是设计用来处理多点触摸的。它会返回执行过的动作的掩码值,不包括该点的索引位。
前一节展示了一个,在屏幕上拖拽对象的例子。另一个常见的场景是平移(panning),平移是指用户通过拖拽移动引起x、y轴方向发生滚动(scrolling)。上面的代码段直接截获了MotionEvent动作来实现拖拽。这一部分的代码段,利用了平台对常用手势的内置支持。它重写了的onScroll()函数。
更详细地说,当用户拖拽手指来平移内容时,函数就会被调用。onScroll()
函数只会在手指按下的情况下被调用,一旦手指离开屏幕了,要么手势终止,要么快速滑动(fling)手势开始(如果手指在离开屏幕前快速移动了一段距离)。关于滚动与快速滑动的更多讨论,可以查看章节。
onScroll()
函数中滑动视窗(viewport)来响应触摸手势的实现:
如同检测常用手势章节中提到的,可以帮助我们检测Android中的常见手势,例如滚动,快速滚动以及长按。对于缩放,Android也提供了ScaleGestureDetector类。当我们想让view能识别额外的手势时,我们可以同时使用和ScaleGestureDetector类。
为了报告检测到的手势事件,手势检测需要一个作为构造函数参数的listener对象。使用ScaleGestureDetector.OnScaleGestureListener。Android提供了类作为帮助类,如果我们不是关注所有的手势事件,我们可以继承(extend)它。
更加复杂的缩放示例
这是本章节提供的示例中一个更复杂的示范。通过使用中的”span”(getCurrentSpanX/Y)和”focus”()功能,InteractiveChart
示例同时支持滚动(平移)以及多指缩放。