page.title=Tracking Movement parent.title=Using Touch Gestures parent.link=index.html trainingnavtop=true next.title=Animating a Scroll Gesture next.link=scroll.html @jd:body

This lesson teaches you to

  1. Track Velocity

You should also read

Try it out

Download the sample

InteractiveChart.zip

This lesson describes how to track movement in touch events.

A new {@link android.view.View#onTouchEvent onTouchEvent()} is triggered with an {@link android.view.MotionEvent#ACTION_MOVE} event whenever the current touch contact position, pressure, or size changes. As described in Detecting Common Gestures, all of these events are recorded in the {@link android.view.MotionEvent} parameter of {@link android.view.View#onTouchEvent onTouchEvent()}.

Because finger-based touch isn't always the most precise form of interaction, detecting touch events is often based more on movement than on simple contact. To help apps distinguish between movement-based gestures (such as a swipe) and non-movement gestures (such as a single tap), Android includes the notion of "touch slop." Touch slop refers to the distance in pixels a user's touch can wander before the gesture is interpreted as a movement-based gesture. For more discussion of this topic, see Managing Touch Events in a ViewGroup.

There are several different ways to track movement in a gesture, depending on the needs of your application. For example:

Track Velocity

You could have a movement-based gesture that is simply based on the distance and/or direction the pointer traveled. But velocity often is a determining factor in tracking a gesture's characteristics or even deciding whether the gesture occurred. To make velocity calculation easier, Android provides the {@link android.view.VelocityTracker} class and the {@link android.support.v4.view.VelocityTrackerCompat} class in the Support Library. {@link android.view.VelocityTracker} helps you track the velocity of touch events. This is useful for gestures in which velocity is part of the criteria for the gesture, such as a fling.

Here is a simple example that illustrates the purpose of the methods in the {@link android.view.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;
    }
}

Note: Note that you should calculate velocity after an {@link android.view.MotionEvent#ACTION_MOVE} event, not after {@link android.view.MotionEvent#ACTION_UP}. After an {@link android.view.MotionEvent#ACTION_UP}, the X and Y velocities will be 0.