blob: fccef2b99304728b927695e020cd466d9ca21934 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
Romain Guyd928d682009-03-31 17:52:16 -070019import android.util.Poolable;
20import android.util.Pool;
Romain Guy2e9bbce2009-04-01 10:40:10 -070021import android.util.Pools;
Romain Guyd928d682009-03-31 17:52:16 -070022import android.util.PoolableManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023
24/**
25 * Helper for tracking the velocity of touch events, for implementing
Jeff Brown2ed24622011-03-14 19:39:54 -070026 * 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.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033 */
Romain Guyd928d682009-03-31 17:52:16 -070034public final class VelocityTracker implements Poolable<VelocityTracker> {
Romain Guy2e9bbce2009-04-01 10:40:10 -070035 private static final Pool<VelocityTracker> sPool = Pools.synchronizedPool(
36 Pools.finitePool(new PoolableManager<VelocityTracker>() {
Romain Guyd928d682009-03-31 17:52:16 -070037 public VelocityTracker newInstance() {
38 return new VelocityTracker();
39 }
40
41 public void onAcquired(VelocityTracker element) {
Romain Guyd928d682009-03-31 17:52:16 -070042 }
43
44 public void onReleased(VelocityTracker element) {
Jeff Brown88cf2fc2010-08-09 18:50:35 -070045 element.clear();
Romain Guyd928d682009-03-31 17:52:16 -070046 }
47 }, 2));
Romain Guyd928d682009-03-31 17:52:16 -070048
Jeff Brown2ed24622011-03-14 19:39:54 -070049 private static final int ACTIVE_POINTER_ID = -1;
50
51 private int mPtr;
Romain Guyd928d682009-03-31 17:52:16 -070052 private VelocityTracker mNext;
53
Jeff Brown2ed24622011-03-14 19:39:54 -070054 private static native int nativeInitialize();
55 private static native void nativeDispose(int ptr);
56 private static native void nativeClear(int ptr);
57 private static native void nativeAddMovement(int ptr, MotionEvent event);
58 private static native void nativeComputeCurrentVelocity(int ptr, int units, float maxVelocity);
59 private static native float nativeGetXVelocity(int ptr, int id);
60 private static native float nativeGetYVelocity(int ptr, int id);
61
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 /**
63 * Retrieve a new VelocityTracker object to watch the velocity of a
64 * motion. Be sure to call {@link #recycle} when done. You should
65 * generally only maintain an active object while tracking a movement,
66 * so that the VelocityTracker can be re-used elsewhere.
Romain Guyd928d682009-03-31 17:52:16 -070067 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068 * @return Returns a new VelocityTracker.
69 */
70 static public VelocityTracker obtain() {
Romain Guyd928d682009-03-31 17:52:16 -070071 return sPool.acquire();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 }
Romain Guyd928d682009-03-31 17:52:16 -070073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 /**
75 * Return a VelocityTracker object back to be re-used by others. You must
76 * not touch the object after calling this function.
77 */
78 public void recycle() {
Romain Guyd928d682009-03-31 17:52:16 -070079 sPool.release(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 }
Romain Guyd928d682009-03-31 17:52:16 -070081
82 /**
83 * @hide
84 */
85 public void setNextPoolable(VelocityTracker element) {
86 mNext = element;
87 }
88
89 /**
90 * @hide
91 */
92 public VelocityTracker getNextPoolable() {
93 return mNext;
94 }
95
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 private VelocityTracker() {
Jeff Brown2ed24622011-03-14 19:39:54 -070097 mPtr = nativeInitialize();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 }
Jeff Brown2ed24622011-03-14 19:39:54 -070099
100 @Override
101 protected void finalize() throws Throwable {
102 try {
103 if (mPtr != 0) {
104 nativeDispose(mPtr);
105 mPtr = 0;
106 }
107 } finally {
108 super.finalize();
109 }
110 }
111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 /**
113 * Reset the velocity tracker back to its initial state.
114 */
115 public void clear() {
Jeff Brown2ed24622011-03-14 19:39:54 -0700116 nativeClear(mPtr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 }
118
119 /**
120 * Add a user's movement to the tracker. You should call this for the
121 * initial {@link MotionEvent#ACTION_DOWN}, the following
122 * {@link MotionEvent#ACTION_MOVE} events that you receive, and the
123 * final {@link MotionEvent#ACTION_UP}. You can, however, call this
124 * for whichever events you desire.
125 *
Jeff Brown2ed24622011-03-14 19:39:54 -0700126 * @param event The MotionEvent you received and would like to track.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 */
Jeff Brown2ed24622011-03-14 19:39:54 -0700128 public void addMovement(MotionEvent event) {
129 if (event == null) {
130 throw new IllegalArgumentException("event must not be null");
Adam Powell73d8fca2010-02-12 16:50:19 -0800131 }
Jeff Brown2ed24622011-03-14 19:39:54 -0700132 nativeAddMovement(mPtr, event);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 }
Romain Guy4296fc42009-07-06 11:48:52 -0700134
135 /**
136 * Equivalent to invoking {@link #computeCurrentVelocity(int, float)} with a maximum
137 * velocity of Float.MAX_VALUE.
138 *
139 * @see #computeCurrentVelocity(int, float)
140 */
141 public void computeCurrentVelocity(int units) {
Jeff Brown2ed24622011-03-14 19:39:54 -0700142 nativeComputeCurrentVelocity(mPtr, units, Float.MAX_VALUE);
Romain Guy4296fc42009-07-06 11:48:52 -0700143 }
144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 /**
146 * Compute the current velocity based on the points that have been
147 * collected. Only call this when you actually want to retrieve velocity
148 * information, as it is relatively expensive. You can then retrieve
149 * the velocity with {@link #getXVelocity()} and
150 * {@link #getYVelocity()}.
151 *
152 * @param units The units you would like the velocity in. A value of 1
153 * provides pixels per millisecond, 1000 provides pixels per second, etc.
Romain Guy4296fc42009-07-06 11:48:52 -0700154 * @param maxVelocity The maximum velocity that can be computed by this method.
155 * This value must be declared in the same unit as the units parameter. This value
156 * must be positive.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 */
Romain Guy4296fc42009-07-06 11:48:52 -0700158 public void computeCurrentVelocity(int units, float maxVelocity) {
Jeff Brown2ed24622011-03-14 19:39:54 -0700159 nativeComputeCurrentVelocity(mPtr, units, maxVelocity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 }
161
162 /**
163 * Retrieve the last computed X velocity. You must first call
164 * {@link #computeCurrentVelocity(int)} before calling this function.
165 *
166 * @return The previously computed X velocity.
167 */
168 public float getXVelocity() {
Jeff Brown2ed24622011-03-14 19:39:54 -0700169 return nativeGetXVelocity(mPtr, ACTIVE_POINTER_ID);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 }
171
172 /**
173 * Retrieve the last computed Y velocity. You must first call
174 * {@link #computeCurrentVelocity(int)} before calling this function.
175 *
176 * @return The previously computed Y velocity.
177 */
178 public float getYVelocity() {
Jeff Brown2ed24622011-03-14 19:39:54 -0700179 return nativeGetYVelocity(mPtr, ACTIVE_POINTER_ID);
Adam Powell8acdb202010-01-06 17:33:52 -0800180 }
181
182 /**
183 * Retrieve the last computed X velocity. You must first call
184 * {@link #computeCurrentVelocity(int)} before calling this function.
185 *
Adam Powell73d8fca2010-02-12 16:50:19 -0800186 * @param id Which pointer's velocity to return.
Adam Powell8acdb202010-01-06 17:33:52 -0800187 * @return The previously computed X velocity.
Adam Powell8acdb202010-01-06 17:33:52 -0800188 */
Adam Powell73d8fca2010-02-12 16:50:19 -0800189 public float getXVelocity(int id) {
Jeff Brown2ed24622011-03-14 19:39:54 -0700190 return nativeGetXVelocity(mPtr, id);
Adam Powell8acdb202010-01-06 17:33:52 -0800191 }
192
193 /**
194 * Retrieve the last computed Y velocity. You must first call
195 * {@link #computeCurrentVelocity(int)} before calling this function.
196 *
Adam Powell73d8fca2010-02-12 16:50:19 -0800197 * @param id Which pointer's velocity to return.
Adam Powell8acdb202010-01-06 17:33:52 -0800198 * @return The previously computed Y velocity.
Adam Powell8acdb202010-01-06 17:33:52 -0800199 */
Adam Powell73d8fca2010-02-12 16:50:19 -0800200 public float getYVelocity(int id) {
Jeff Brown2ed24622011-03-14 19:39:54 -0700201 return nativeGetYVelocity(mPtr, id);
Jeff Brown88cf2fc2010-08-09 18:50:35 -0700202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203}