| && repo sync -j8 | 518edbf | 2012-11-30 16:28:27 -0800 | [diff] [blame] | 1 | page.title=Tracking Movement |
| 2 | parent.title=Using Touch Gestures |
| 3 | parent.link=index.html |
| 4 | |
| 5 | trainingnavtop=true |
| 6 | next.title=Animating a Scroll Gesture |
| 7 | next.link=scroll.html |
| 8 | |
| 9 | @jd:body |
| 10 | |
| 11 | <div id="tb-wrapper"> |
| 12 | <div id="tb"> |
| 13 | |
| 14 | <!-- table of contents --> |
| 15 | <h2>This lesson teaches you to</h2> |
| 16 | <ol> |
| 17 | <li><a href="#velocity">Track Velocity</a></li> |
| 18 | </ol> |
| 19 | |
| 20 | <!-- other docs (NOT javadocs) --> |
| 21 | <h2>You should also read</h2> |
| 22 | |
| 23 | <ul> |
| 24 | <li><a href="http://developer.android.com/guide/topics/ui/ui-events.html">Input Events</a> API Guide |
| 25 | </li> |
| 26 | <li><a href="{@docRoot}guide/topics/sensors/sensors_overview.html">Sensors Overview</a></li> |
| && repo sync -j8 | 518edbf | 2012-11-30 16:28:27 -0800 | [diff] [blame] | 27 | <li><a href="{@docRoot}training/custom-views/making-interactive.html">Making the View Interactive</a> </li> |
| 28 | <li>Design Guide for <a href="{@docRoot}design/patterns/gestures.html">Gestures</a></li> |
| 29 | <li>Design Guide for <a href="{@docRoot}design/style/touch-feedback.html">Touch Feedback</a></li> |
| 30 | </ul> |
| 31 | |
| kmccormick | e23f97b | 2013-03-12 14:46:07 -0700 | [diff] [blame] | 32 | <h2>Try it out</h2> |
| 33 | |
| 34 | <div class="download-box"> |
| 35 | <a href="{@docRoot}shareables/training/InteractiveChart.zip" |
| 36 | class="button">Download the sample</a> |
| 37 | <p class="filename">InteractiveChart.zip</p> |
| 38 | </div> |
| && repo sync -j8 | 518edbf | 2012-11-30 16:28:27 -0800 | [diff] [blame] | 39 | |
| 40 | </div> |
| 41 | </div> |
| 42 | |
| 43 | <p>This lesson describes how to track movement in touch events.</p> |
| 44 | |
| 45 | <p>A new {@link |
| 46 | android.view.View#onTouchEvent onTouchEvent()} is triggered with an {@link |
| 47 | android.view.MotionEvent#ACTION_MOVE} event whenever the current touch contact |
| 48 | position, pressure, or size changes. As described in <a |
| 49 | href="detector.html">Detecting Common Gestures</a>, all of these events are |
| 50 | recorded in the {@link android.view.MotionEvent} parameter of {@link |
| 51 | android.view.View#onTouchEvent onTouchEvent()}.</p> |
| 52 | |
| 53 | <p>Because finger-based touch isn't always the most precise form of interaction, |
| 54 | detecting touch events is often based more on movement than on simple contact. |
| 55 | To help apps distinguish between movement-based gestures (such as a swipe) and |
| 56 | non-movement gestures (such as a single tap), Android includes the notion of |
| 57 | "touch slop." Touch slop refers to the distance in pixels a user's touch can wander |
| 58 | before the gesture is interpreted as a movement-based gesture. For more discussion of this |
| 59 | topic, see <a href="viewgroup.html#vc">Managing Touch Events in a ViewGroup</a>.</p> |
| 60 | |
| 61 | |
| 62 | |
| 63 | <p>There are several different ways to track movement in a gesture, depending on |
| 64 | the needs of your application. For example:</p> |
| 65 | |
| 66 | <ul> |
| 67 | |
| 68 | <li>The starting and ending position of a pointer (for example, move an |
| 69 | on-screen object from point A to point B).</li> |
| 70 | |
| 71 | <li>The direction the pointer is traveling in, as determined by the x and y coordinates.</li> |
| 72 | |
| 73 | <li>History. You can find the size of a gesture's history by calling the {@link |
| 74 | android.view.MotionEvent} method {@link android.view.MotionEvent#getHistorySize |
| 75 | getHistorySize()}. You can then obtain the positions, sizes, time, and pressures |
| 76 | of each of the historical events by using the motion event's {@code |
| 77 | getHistorical<em><Value></em>} methods. History is useful when rendering a trail of the user's finger, |
| 78 | such as for touch drawing. See the {@link android.view.MotionEvent} reference for |
| 79 | details.</li> |
| 80 | |
| 81 | <li>The velocity of the pointer as it moves across the touch screen.</li> |
| 82 | |
| 83 | </ul> |
| 84 | |
| 85 | |
| 86 | |
| 87 | <h2 id="velocity">Track Velocity</h2> |
| 88 | |
| 89 | <p> 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 |
| 90 | determining factor in tracking a gesture's characteristics or even deciding |
| 91 | whether the gesture occurred. To make velocity calculation easier, Android |
| 92 | provides the {@link android.view.VelocityTracker} class and the |
| 93 | {@link android.support.v4.view.VelocityTrackerCompat} class in the |
| Scott Main | 4e2c9dc | 2013-07-23 19:35:17 -0700 | [diff] [blame] | 94 | <a href="{@docRoot}tools/support-library/index.html">Support Library</a>. |
| && repo sync -j8 | 518edbf | 2012-11-30 16:28:27 -0800 | [diff] [blame] | 95 | {@link |
| 96 | android.view.VelocityTracker} helps you track the velocity of touch events. This |
| 97 | is useful for gestures in which velocity is part of the criteria for the |
| 98 | gesture, such as a fling.</p> |
| 99 | |
| 100 | |
| 101 | <p>Here is a simple example that illustrates the purpose of the methods in the |
| 102 | {@link android.view.VelocityTracker} API:</p> |
| 103 | |
| 104 | <pre>public class MainActivity extends Activity { |
| 105 | private static final String DEBUG_TAG = "Velocity"; |
| 106 | ... |
| 107 | private VelocityTracker mVelocityTracker = null; |
| 108 | @Override |
| 109 | public boolean onTouchEvent(MotionEvent event) { |
| 110 | int index = event.getActionIndex(); |
| 111 | int action = event.getActionMasked(); |
| 112 | int pointerId = event.getPointerId(index); |
| 113 | |
| 114 | switch(action) { |
| 115 | case MotionEvent.ACTION_DOWN: |
| 116 | if(mVelocityTracker == null) { |
| 117 | // Retrieve a new VelocityTracker object to watch the velocity of a motion. |
| 118 | mVelocityTracker = VelocityTracker.obtain(); |
| 119 | } |
| 120 | else { |
| 121 | // Reset the velocity tracker back to its initial state. |
| 122 | mVelocityTracker.clear(); |
| 123 | } |
| 124 | // Add a user's movement to the tracker. |
| 125 | mVelocityTracker.addMovement(event); |
| 126 | break; |
| 127 | case MotionEvent.ACTION_MOVE: |
| 128 | mVelocityTracker.addMovement(event); |
| 129 | // When you want to determine the velocity, call |
| 130 | // computeCurrentVelocity(). Then call getXVelocity() |
| 131 | // and getYVelocity() to retrieve the velocity for each pointer ID. |
| 132 | mVelocityTracker.computeCurrentVelocity(1000); |
| 133 | // Log velocity of pixels per second |
| 134 | // Best practice to use VelocityTrackerCompat where possible. |
| 135 | Log.d("", "X velocity: " + |
| 136 | VelocityTrackerCompat.getXVelocity(mVelocityTracker, |
| 137 | pointerId)); |
| 138 | Log.d("", "Y velocity: " + |
| 139 | VelocityTrackerCompat.getYVelocity(mVelocityTracker, |
| 140 | pointerId)); |
| 141 | break; |
| 142 | case MotionEvent.ACTION_UP: |
| 143 | case MotionEvent.ACTION_CANCEL: |
| 144 | // Return a VelocityTracker object back to be re-used by others. |
| 145 | mVelocityTracker.recycle(); |
| 146 | break; |
| 147 | } |
| 148 | return true; |
| 149 | } |
| 150 | } |
| 151 | </pre> |
| 152 | |
| 153 | <p class="note"><strong>Note:</strong> Note that you should calculate velocity after an |
| 154 | {@link android.view.MotionEvent#ACTION_MOVE} event, |
| 155 | not after {@link android.view.MotionEvent#ACTION_UP}. After an {@link android.view.MotionEvent#ACTION_UP}, |
| 156 | the X and Y velocities will be 0. |
| 157 | </p> |