ab76fa7f6849540750928b82685dc595f19297a8
[pub/Android/ownCloud.git] / actionbarsherlock / src / com / actionbarsherlock / internal / nineoldandroids / animation / Keyframe.java
1 /*
2 * Copyright (C) 2010 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
17 package com.actionbarsherlock.internal.nineoldandroids.animation;
18
19 import android.view.animation.Interpolator;
20
21 /**
22 * This class holds a time/value pair for an animation. The Keyframe class is used
23 * by {@link ValueAnimator} to define the values that the animation target will have over the course
24 * of the animation. As the time proceeds from one keyframe to the other, the value of the
25 * target object will animate between the value at the previous keyframe and the value at the
26 * next keyframe. Each keyframe also holds an optional {@link TimeInterpolator}
27 * object, which defines the time interpolation over the intervalue preceding the keyframe.
28 *
29 * <p>The Keyframe class itself is abstract. The type-specific factory methods will return
30 * a subclass of Keyframe specific to the type of value being stored. This is done to improve
31 * performance when dealing with the most common cases (e.g., <code>float</code> and
32 * <code>int</code> values). Other types will fall into a more general Keyframe class that
33 * treats its values as Objects. Unless your animation requires dealing with a custom type
34 * or a data structure that needs to be animated directly (and evaluated using an implementation
35 * of {@link TypeEvaluator}), you should stick to using float and int as animations using those
36 * types have lower runtime overhead than other types.</p>
37 */
38 @SuppressWarnings("rawtypes")
39 public abstract class Keyframe implements Cloneable {
40 /**
41 * The time at which mValue will hold true.
42 */
43 float mFraction;
44
45 /**
46 * The type of the value in this Keyframe. This type is determined at construction time,
47 * based on the type of the <code>value</code> object passed into the constructor.
48 */
49 Class mValueType;
50
51 /**
52 * The optional time interpolator for the interval preceding this keyframe. A null interpolator
53 * (the default) results in linear interpolation over the interval.
54 */
55 private /*Time*/Interpolator mInterpolator = null;
56
57 /**
58 * Flag to indicate whether this keyframe has a valid value. This flag is used when an
59 * animation first starts, to populate placeholder keyframes with real values derived
60 * from the target object.
61 */
62 boolean mHasValue = false;
63
64 /**
65 * Constructs a Keyframe object with the given time and value. The time defines the
66 * time, as a proportion of an overall animation's duration, at which the value will hold true
67 * for the animation. The value for the animation between keyframes will be calculated as
68 * an interpolation between the values at those keyframes.
69 *
70 * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
71 * of time elapsed of the overall animation duration.
72 * @param value The value that the object will animate to as the animation time approaches
73 * the time in this keyframe, and the the value animated from as the time passes the time in
74 * this keyframe.
75 */
76 public static Keyframe ofInt(float fraction, int value) {
77 return new IntKeyframe(fraction, value);
78 }
79
80 /**
81 * Constructs a Keyframe object with the given time. The value at this time will be derived
82 * from the target object when the animation first starts (note that this implies that keyframes
83 * with no initial value must be used as part of an {@link ObjectAnimator}).
84 * The time defines the
85 * time, as a proportion of an overall animation's duration, at which the value will hold true
86 * for the animation. The value for the animation between keyframes will be calculated as
87 * an interpolation between the values at those keyframes.
88 *
89 * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
90 * of time elapsed of the overall animation duration.
91 */
92 public static Keyframe ofInt(float fraction) {
93 return new IntKeyframe(fraction);
94 }
95
96 /**
97 * Constructs a Keyframe object with the given time and value. The time defines the
98 * time, as a proportion of an overall animation's duration, at which the value will hold true
99 * for the animation. The value for the animation between keyframes will be calculated as
100 * an interpolation between the values at those keyframes.
101 *
102 * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
103 * of time elapsed of the overall animation duration.
104 * @param value The value that the object will animate to as the animation time approaches
105 * the time in this keyframe, and the the value animated from as the time passes the time in
106 * this keyframe.
107 */
108 public static Keyframe ofFloat(float fraction, float value) {
109 return new FloatKeyframe(fraction, value);
110 }
111
112 /**
113 * Constructs a Keyframe object with the given time. The value at this time will be derived
114 * from the target object when the animation first starts (note that this implies that keyframes
115 * with no initial value must be used as part of an {@link ObjectAnimator}).
116 * The time defines the
117 * time, as a proportion of an overall animation's duration, at which the value will hold true
118 * for the animation. The value for the animation between keyframes will be calculated as
119 * an interpolation between the values at those keyframes.
120 *
121 * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
122 * of time elapsed of the overall animation duration.
123 */
124 public static Keyframe ofFloat(float fraction) {
125 return new FloatKeyframe(fraction);
126 }
127
128 /**
129 * Constructs a Keyframe object with the given time and value. The time defines the
130 * time, as a proportion of an overall animation's duration, at which the value will hold true
131 * for the animation. The value for the animation between keyframes will be calculated as
132 * an interpolation between the values at those keyframes.
133 *
134 * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
135 * of time elapsed of the overall animation duration.
136 * @param value The value that the object will animate to as the animation time approaches
137 * the time in this keyframe, and the the value animated from as the time passes the time in
138 * this keyframe.
139 */
140 public static Keyframe ofObject(float fraction, Object value) {
141 return new ObjectKeyframe(fraction, value);
142 }
143
144 /**
145 * Constructs a Keyframe object with the given time. The value at this time will be derived
146 * from the target object when the animation first starts (note that this implies that keyframes
147 * with no initial value must be used as part of an {@link ObjectAnimator}).
148 * The time defines the
149 * time, as a proportion of an overall animation's duration, at which the value will hold true
150 * for the animation. The value for the animation between keyframes will be calculated as
151 * an interpolation between the values at those keyframes.
152 *
153 * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
154 * of time elapsed of the overall animation duration.
155 */
156 public static Keyframe ofObject(float fraction) {
157 return new ObjectKeyframe(fraction, null);
158 }
159
160 /**
161 * Indicates whether this keyframe has a valid value. This method is called internally when
162 * an {@link ObjectAnimator} first starts; keyframes without values are assigned values at
163 * that time by deriving the value for the property from the target object.
164 *
165 * @return boolean Whether this object has a value assigned.
166 */
167 public boolean hasValue() {
168 return mHasValue;
169 }
170
171 /**
172 * Gets the value for this Keyframe.
173 *
174 * @return The value for this Keyframe.
175 */
176 public abstract Object getValue();
177
178 /**
179 * Sets the value for this Keyframe.
180 *
181 * @param value value for this Keyframe.
182 */
183 public abstract void setValue(Object value);
184
185 /**
186 * Gets the time for this keyframe, as a fraction of the overall animation duration.
187 *
188 * @return The time associated with this keyframe, as a fraction of the overall animation
189 * duration. This should be a value between 0 and 1.
190 */
191 public float getFraction() {
192 return mFraction;
193 }
194
195 /**
196 * Sets the time for this keyframe, as a fraction of the overall animation duration.
197 *
198 * @param fraction time associated with this keyframe, as a fraction of the overall animation
199 * duration. This should be a value between 0 and 1.
200 */
201 public void setFraction(float fraction) {
202 mFraction = fraction;
203 }
204
205 /**
206 * Gets the optional interpolator for this Keyframe. A value of <code>null</code> indicates
207 * that there is no interpolation, which is the same as linear interpolation.
208 *
209 * @return The optional interpolator for this Keyframe.
210 */
211 public /*Time*/Interpolator getInterpolator() {
212 return mInterpolator;
213 }
214
215 /**
216 * Sets the optional interpolator for this Keyframe. A value of <code>null</code> indicates
217 * that there is no interpolation, which is the same as linear interpolation.
218 *
219 * @return The optional interpolator for this Keyframe.
220 */
221 public void setInterpolator(/*Time*/Interpolator interpolator) {
222 mInterpolator = interpolator;
223 }
224
225 /**
226 * Gets the type of keyframe. This information is used by ValueAnimator to determine the type of
227 * {@link TypeEvaluator} to use when calculating values between keyframes. The type is based
228 * on the type of Keyframe created.
229 *
230 * @return The type of the value stored in the Keyframe.
231 */
232 public Class getType() {
233 return mValueType;
234 }
235
236 @Override
237 public abstract Keyframe clone();
238
239 /**
240 * This internal subclass is used for all types which are not int or float.
241 */
242 static class ObjectKeyframe extends Keyframe {
243
244 /**
245 * The value of the animation at the time mFraction.
246 */
247 Object mValue;
248
249 ObjectKeyframe(float fraction, Object value) {
250 mFraction = fraction;
251 mValue = value;
252 mHasValue = (value != null);
253 mValueType = mHasValue ? value.getClass() : Object.class;
254 }
255
256 public Object getValue() {
257 return mValue;
258 }
259
260 public void setValue(Object value) {
261 mValue = value;
262 mHasValue = (value != null);
263 }
264
265 @Override
266 public ObjectKeyframe clone() {
267 ObjectKeyframe kfClone = new ObjectKeyframe(getFraction(), mValue);
268 kfClone.setInterpolator(getInterpolator());
269 return kfClone;
270 }
271 }
272
273 /**
274 * Internal subclass used when the keyframe value is of type int.
275 */
276 static class IntKeyframe extends Keyframe {
277
278 /**
279 * The value of the animation at the time mFraction.
280 */
281 int mValue;
282
283 IntKeyframe(float fraction, int value) {
284 mFraction = fraction;
285 mValue = value;
286 mValueType = int.class;
287 mHasValue = true;
288 }
289
290 IntKeyframe(float fraction) {
291 mFraction = fraction;
292 mValueType = int.class;
293 }
294
295 public int getIntValue() {
296 return mValue;
297 }
298
299 public Object getValue() {
300 return mValue;
301 }
302
303 public void setValue(Object value) {
304 if (value != null && value.getClass() == Integer.class) {
305 mValue = ((Integer)value).intValue();
306 mHasValue = true;
307 }
308 }
309
310 @Override
311 public IntKeyframe clone() {
312 IntKeyframe kfClone = new IntKeyframe(getFraction(), mValue);
313 kfClone.setInterpolator(getInterpolator());
314 return kfClone;
315 }
316 }
317
318 /**
319 * Internal subclass used when the keyframe value is of type float.
320 */
321 static class FloatKeyframe extends Keyframe {
322 /**
323 * The value of the animation at the time mFraction.
324 */
325 float mValue;
326
327 FloatKeyframe(float fraction, float value) {
328 mFraction = fraction;
329 mValue = value;
330 mValueType = float.class;
331 mHasValue = true;
332 }
333
334 FloatKeyframe(float fraction) {
335 mFraction = fraction;
336 mValueType = float.class;
337 }
338
339 public float getFloatValue() {
340 return mValue;
341 }
342
343 public Object getValue() {
344 return mValue;
345 }
346
347 public void setValue(Object value) {
348 if (value != null && value.getClass() == Float.class) {
349 mValue = ((Float)value).floatValue();
350 mHasValue = true;
351 }
352 }
353
354 @Override
355 public FloatKeyframe clone() {
356 FloatKeyframe kfClone = new FloatKeyframe(getFraction(), mValue);
357 kfClone.setInterpolator(getInterpolator());
358 return kfClone;
359 }
360 }
361 }