这个课程描述了如何在触摸事件中跟踪移动。 


 


无论当前触摸接触点的位置,压力,或者大小的变化,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。