Skip to content

Most visited

Recently visited


Tracking Movement

This lesson teaches you to

  1. Track Velocity

You should also read

Try it out

Download the sample

This lesson describes how to track movement in touch events.

A new onTouchEvent() is triggered with an 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 MotionEvent parameter of 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 VelocityTracker class and the VelocityTrackerCompat class in the Support Library. 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 VelocityTracker API:

public class MainActivity extends Activity {
    private static final String DEBUG_TAG = "Velocity";
    private VelocityTracker mVelocityTracker = null;
    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.
                // Add a user's movement to the tracker.
            case MotionEvent.ACTION_MOVE:
                // When you want to determine the velocity, call
                // computeCurrentVelocity(). Then call getXVelocity()
                // and getYVelocity() to retrieve the velocity for each pointer ID.
                // Log velocity of pixels per second
                // Best practice to use VelocityTrackerCompat where possible.
                Log.d("", "X velocity: " +
                Log.d("", "Y velocity: " +
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                // Return a VelocityTracker object back to be re-used by others.
        return true;

Note: Note that you should calculate velocity after an ACTION_MOVE event, not after ACTION_UP. After an ACTION_UP, the X and Y velocities will be 0.

This site uses cookies to store your preferences for site-specific language and display options.


This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.