VelocityTracker.java revision 8643aa0179e598e78d938c59035389054535a229
1/* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.view; 18 19import android.util.Poolable; 20import android.util.Pool; 21import android.util.Pools; 22import android.util.PoolableManager; 23 24/** 25 * Helper for tracking the velocity of touch events, for implementing 26 * flinging and other such gestures. 27 * 28 * Use {@link #obtain} to retrieve a new instance of the class when you are going 29 * to begin tracking. Put the motion events you receive into it with 30 * {@link #addMovement(MotionEvent)}. When you want to determine the velocity call 31 * {@link #computeCurrentVelocity(int)} and then call {@link #getXVelocity(int)} 32 * and {@link #getXVelocity(int)} to retrieve the velocity for each pointer id. 33 */ 34public final class VelocityTracker implements Poolable<VelocityTracker> { 35 private static final Pool<VelocityTracker> sPool = Pools.synchronizedPool( 36 Pools.finitePool(new PoolableManager<VelocityTracker>() { 37 public VelocityTracker newInstance() { 38 return new VelocityTracker(); 39 } 40 41 public void onAcquired(VelocityTracker element) { 42 } 43 44 public void onReleased(VelocityTracker element) { 45 element.clear(); 46 } 47 }, 2)); 48 49 private static final int ACTIVE_POINTER_ID = -1; 50 51 private int mPtr; 52 private VelocityTracker mNext; 53 private boolean mIsPooled; 54 55 private static native int nativeInitialize(); 56 private static native void nativeDispose(int ptr); 57 private static native void nativeClear(int ptr); 58 private static native void nativeAddMovement(int ptr, MotionEvent event); 59 private static native void nativeComputeCurrentVelocity(int ptr, int units, float maxVelocity); 60 private static native float nativeGetXVelocity(int ptr, int id); 61 private static native float nativeGetYVelocity(int ptr, int id); 62 63 /** 64 * Retrieve a new VelocityTracker object to watch the velocity of a 65 * motion. Be sure to call {@link #recycle} when done. You should 66 * generally only maintain an active object while tracking a movement, 67 * so that the VelocityTracker can be re-used elsewhere. 68 * 69 * @return Returns a new VelocityTracker. 70 */ 71 static public VelocityTracker obtain() { 72 return sPool.acquire(); 73 } 74 75 /** 76 * Return a VelocityTracker object back to be re-used by others. You must 77 * not touch the object after calling this function. 78 */ 79 public void recycle() { 80 sPool.release(this); 81 } 82 83 /** 84 * @hide 85 */ 86 public void setNextPoolable(VelocityTracker element) { 87 mNext = element; 88 } 89 90 /** 91 * @hide 92 */ 93 public VelocityTracker getNextPoolable() { 94 return mNext; 95 } 96 97 /** 98 * @hide 99 */ 100 public boolean isPooled() { 101 return mIsPooled; 102 } 103 104 /** 105 * @hide 106 */ 107 public void setPooled(boolean isPooled) { 108 mIsPooled = isPooled; 109 } 110 111 private VelocityTracker() { 112 mPtr = nativeInitialize(); 113 } 114 115 @Override 116 protected void finalize() throws Throwable { 117 try { 118 if (mPtr != 0) { 119 nativeDispose(mPtr); 120 mPtr = 0; 121 } 122 } finally { 123 super.finalize(); 124 } 125 } 126 127 /** 128 * Reset the velocity tracker back to its initial state. 129 */ 130 public void clear() { 131 nativeClear(mPtr); 132 } 133 134 /** 135 * Add a user's movement to the tracker. You should call this for the 136 * initial {@link MotionEvent#ACTION_DOWN}, the following 137 * {@link MotionEvent#ACTION_MOVE} events that you receive, and the 138 * final {@link MotionEvent#ACTION_UP}. You can, however, call this 139 * for whichever events you desire. 140 * 141 * @param event The MotionEvent you received and would like to track. 142 */ 143 public void addMovement(MotionEvent event) { 144 if (event == null) { 145 throw new IllegalArgumentException("event must not be null"); 146 } 147 nativeAddMovement(mPtr, event); 148 } 149 150 /** 151 * Equivalent to invoking {@link #computeCurrentVelocity(int, float)} with a maximum 152 * velocity of Float.MAX_VALUE. 153 * 154 * @see #computeCurrentVelocity(int, float) 155 */ 156 public void computeCurrentVelocity(int units) { 157 nativeComputeCurrentVelocity(mPtr, units, Float.MAX_VALUE); 158 } 159 160 /** 161 * Compute the current velocity based on the points that have been 162 * collected. Only call this when you actually want to retrieve velocity 163 * information, as it is relatively expensive. You can then retrieve 164 * the velocity with {@link #getXVelocity()} and 165 * {@link #getYVelocity()}. 166 * 167 * @param units The units you would like the velocity in. A value of 1 168 * provides pixels per millisecond, 1000 provides pixels per second, etc. 169 * @param maxVelocity The maximum velocity that can be computed by this method. 170 * This value must be declared in the same unit as the units parameter. This value 171 * must be positive. 172 */ 173 public void computeCurrentVelocity(int units, float maxVelocity) { 174 nativeComputeCurrentVelocity(mPtr, units, maxVelocity); 175 } 176 177 /** 178 * Retrieve the last computed X velocity. You must first call 179 * {@link #computeCurrentVelocity(int)} before calling this function. 180 * 181 * @return The previously computed X velocity. 182 */ 183 public float getXVelocity() { 184 return nativeGetXVelocity(mPtr, ACTIVE_POINTER_ID); 185 } 186 187 /** 188 * Retrieve the last computed Y velocity. You must first call 189 * {@link #computeCurrentVelocity(int)} before calling this function. 190 * 191 * @return The previously computed Y velocity. 192 */ 193 public float getYVelocity() { 194 return nativeGetYVelocity(mPtr, ACTIVE_POINTER_ID); 195 } 196 197 /** 198 * Retrieve the last computed X velocity. You must first call 199 * {@link #computeCurrentVelocity(int)} before calling this function. 200 * 201 * @param id Which pointer's velocity to return. 202 * @return The previously computed X velocity. 203 */ 204 public float getXVelocity(int id) { 205 return nativeGetXVelocity(mPtr, id); 206 } 207 208 /** 209 * Retrieve the last computed Y velocity. You must first call 210 * {@link #computeCurrentVelocity(int)} before calling this function. 211 * 212 * @param id Which pointer's velocity to return. 213 * @return The previously computed Y velocity. 214 */ 215 public float getYVelocity(int id) { 216 return nativeGetYVelocity(mPtr, id); 217 } 218} 219