这个课程描述了如何在触摸事件中跟踪移动。
无论当前触摸接触点的位置,压力,或者大小的变化,onTouchEvenet()方法被一个ACTION_MOVE事件触发。正如在Detecting Common Gestures中描述,所有的这些事件都被记录在onTouchEvent()方法的MotionEvent参数中。
因为基于手指的触摸不总是最精确的交互形式,检测触摸时间经常是基于移动而不是简单的触摸。为了帮助应用程序区分在基于移动的手势(例如swip)和没有移动的手势(例如一个单独的轻敲),Android包含”触摸溢出“的概念。触摸溢出在手势被翻译为一个基于移动的手势之前,引用了用户的触摸移动的像素距离。更多这个话题的讨论,查阅Managing Touch Evenet in a ViewGroup。
这里有多种不同的方式来在一个手势中跟踪移动,基于你的应用程序的需要。例如:
- 一个点的开始和结束的位置(例如,移动一个屏幕对象,从点A到点B)。
- 点移动的方向,通过x和y坐标来被决定。
- 历史。通过调用MotionEvent方法getHistorySize()方法,你能找到这个手势的历史的大小。你然后通过这个运动事件的getHistorical<Value>方法,能获得每个历史事件的位置,大小,时间,和压力。当描绘一个用户的手指的轨迹的时候,历史是非常有用的,例如触摸绘制。查看MotionEvent参考详情。
- 这个点它在屏幕上移动的速率。
跟踪速度
—————————————————————————————————————————————————————————————————
你能拥有一个基于移动的手势,它仅仅基于点移动的距离和/或者方向。但是速率经常是跟踪一个手势的特征,或者甚至是决定一个手势是否发生的决定因素。为了使速率计算简单,Android在支持库中提供了VelocityTracker类和VelocityTrackerCompat类。VelocityTracker帮助你跟踪这个触摸事件的速率。这对于手势是非常有用的,在速率是这个手势的准则的时候,例如一个fling。
下面是一个简单示例,它说明了在VelocityTracker API中方法的目的:
public class MainActivity extends Activity {
private static final String DEBUG_TAG = "Velocity";
...
private VelocityTracker mVelocityTracker = null;
@Override
public boolean onTouchEvent(MotionEvent event) {
int index = event.getActionIndex();
int action = event.getActionMasked();
int pointerId = event.getPointerId(index);
switch(action) {
case MotionEvent.ACTION_DOWN:
if(mVelocityTracker == null) {
// Retrieve a new VelocityTracker object to watch the velocity of a motion.
mVelocityTracker = VelocityTracker.obtain();
}
else {
// Reset the velocity tracker back to its initial state.
mVelocityTracker.clear();
}
// Add a user's movement to the tracker.
mVelocityTracker.addMovement(event);
break;
case MotionEvent.ACTION_MOVE:
mVelocityTracker.addMovement(event);
// When you want to determine the velocity, call
// computeCurrentVelocity(). Then call getXVelocity()
// and getYVelocity() to retrieve the velocity for each pointer ID.
mVelocityTracker.computeCurrentVelocity(1000);
// Log velocity of pixels per second
// Best practice to use VelocityTrackerCompat where possible.
Log.d("", "X velocity: " +
VelocityTrackerCompat.getXVelocity(mVelocityTracker,
pointerId));
Log.d("", "Y velocity: " +
VelocityTrackerCompat.getYVelocity(mVelocityTracker,
pointerId));
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// Return a VelocityTracker object back to be re-used by others.
mVelocityTracker.recycle();
break;
}
return true;
}
}
注意:
注意你应该在一个ACTION_MOVE事件之后计算速率,不要在ACTION_UP。在ACTION_UP之后,X和Y速度将为0。