blob: 38043b2ba763df340176079c97faa2b68fcf4c22 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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.animation;
18
19import org.xmlpull.v1.XmlPullParser;
20import org.xmlpull.v1.XmlPullParserException;
21
22import android.content.Context;
23import android.content.res.XmlResourceParser;
24import android.content.res.Resources.NotFoundException;
25import android.util.AttributeSet;
26import android.util.Xml;
27import android.os.SystemClock;
28
29import java.io.IOException;
30
31/**
32 * Defines common utilities for working with animations.
33 *
34 */
35public class AnimationUtils {
Chet Haasef54a8d72010-07-22 14:44:59 -070036
37 /**
Chet Haasea18a86b2010-09-07 13:20:00 -070038 * These flags are used when parsing AnimatorSet objects
Chet Haasef54a8d72010-07-22 14:44:59 -070039 */
40 private static final int TOGETHER = 0;
41 private static final int SEQUENTIALLY = 1;
42
43
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044 /**
45 * Returns the current animation time in milliseconds. This time should be used when invoking
46 * {@link Animation#setStartTime(long)}. Refer to {@link android.os.SystemClock} for more
47 * information about the different available clocks. The clock used by this method is
48 * <em>not</em> the "wall" clock (it is not {@link System#currentTimeMillis}).
49 *
50 * @return the current animation time in milliseconds
51 *
52 * @see android.os.SystemClock
53 */
54 public static long currentAnimationTimeMillis() {
55 return SystemClock.uptimeMillis();
56 }
57
58 /**
59 * Loads an {@link Animation} object from a resource
Chet Haasef54a8d72010-07-22 14:44:59 -070060 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 * @param context Application context used to access resources
62 * @param id The resource id of the animation to load
63 * @return The animation object reference by the specified id
64 * @throws NotFoundException when the animation cannot be loaded
65 */
66 public static Animation loadAnimation(Context context, int id)
67 throws NotFoundException {
68
69 XmlResourceParser parser = null;
70 try {
71 parser = context.getResources().getAnimation(id);
72 return createAnimationFromXml(context, parser);
73 } catch (XmlPullParserException ex) {
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -070074 NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
75 Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 rnf.initCause(ex);
77 throw rnf;
78 } catch (IOException ex) {
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -070079 NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
80 Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 rnf.initCause(ex);
82 throw rnf;
83 } finally {
84 if (parser != null) parser.close();
85 }
86 }
87
88 private static Animation createAnimationFromXml(Context c, XmlPullParser parser)
89 throws XmlPullParserException, IOException {
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -070090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 return createAnimationFromXml(c, parser, null, Xml.asAttributeSet(parser));
92 }
Chet Haasef54a8d72010-07-22 14:44:59 -070093
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -070094 private static Animation createAnimationFromXml(Context c, XmlPullParser parser,
95 AnimationSet parent, AttributeSet attrs) throws XmlPullParserException, IOException {
Chet Haasef54a8d72010-07-22 14:44:59 -070096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 Animation anim = null;
Chet Haasef54a8d72010-07-22 14:44:59 -070098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 // Make sure we are on a start tag.
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700100 int type;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 int depth = parser.getDepth();
102
103 while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
104 && type != XmlPullParser.END_DOCUMENT) {
105
106 if (type != XmlPullParser.START_TAG) {
107 continue;
108 }
109
110 String name = parser.getName();
Chet Haasef54a8d72010-07-22 14:44:59 -0700111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 if (name.equals("set")) {
113 anim = new AnimationSet(c, attrs);
114 createAnimationFromXml(c, parser, (AnimationSet)anim, attrs);
115 } else if (name.equals("alpha")) {
116 anim = new AlphaAnimation(c, attrs);
117 } else if (name.equals("scale")) {
118 anim = new ScaleAnimation(c, attrs);
119 } else if (name.equals("rotate")) {
120 anim = new RotateAnimation(c, attrs);
121 } else if (name.equals("translate")) {
122 anim = new TranslateAnimation(c, attrs);
123 } else {
124 throw new RuntimeException("Unknown animation name: " + parser.getName());
125 }
126
127 if (parent != null) {
128 parent.addAnimation(anim);
129 }
130 }
Chet Haasef54a8d72010-07-22 14:44:59 -0700131
132 return anim;
133
134 }
135
Chet Haase2d46fcc2011-12-19 18:01:05 -0800136 /**
137 * Loads a {@link LayoutAnimationController} object from a resource
138 *
139 * @param context Application context used to access resources
140 * @param id The resource id of the animation to load
141 * @return The animation object reference by the specified id
142 * @throws NotFoundException when the layout animation controller cannot be loaded
143 */
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700144 public static LayoutAnimationController loadLayoutAnimation(Context context, int id)
145 throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146
147 XmlResourceParser parser = null;
148 try {
149 parser = context.getResources().getAnimation(id);
150 return createLayoutAnimationFromXml(context, parser);
151 } catch (XmlPullParserException ex) {
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700152 NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
153 Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 rnf.initCause(ex);
155 throw rnf;
156 } catch (IOException ex) {
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700157 NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
158 Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 rnf.initCause(ex);
160 throw rnf;
161 } finally {
162 if (parser != null) parser.close();
163 }
164 }
165
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700166 private static LayoutAnimationController createLayoutAnimationFromXml(Context c,
167 XmlPullParser parser) throws XmlPullParserException, IOException {
168
169 return createLayoutAnimationFromXml(c, parser, Xml.asAttributeSet(parser));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 }
171
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700172 private static LayoutAnimationController createLayoutAnimationFromXml(Context c,
173 XmlPullParser parser, AttributeSet attrs) throws XmlPullParserException, IOException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174
175 LayoutAnimationController controller = null;
176
177 int type;
178 int depth = parser.getDepth();
179
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700180 while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 && type != XmlPullParser.END_DOCUMENT) {
182
183 if (type != XmlPullParser.START_TAG) {
184 continue;
185 }
186
187 String name = parser.getName();
188
189 if ("layoutAnimation".equals(name)) {
190 controller = new LayoutAnimationController(c, attrs);
191 } else if ("gridLayoutAnimation".equals(name)) {
192 controller = new GridLayoutAnimationController(c, attrs);
193 } else {
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700194 throw new RuntimeException("Unknown layout animation name: " + name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195 }
196 }
197
198 return controller;
199 }
200
201 /**
202 * Make an animation for objects becoming visible. Uses a slide and fade
203 * effect.
204 *
205 * @param c Context for loading resources
206 * @param fromLeft is the object to be animated coming from the left
207 * @return The new animation
208 */
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700209 public static Animation makeInAnimation(Context c, boolean fromLeft) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 Animation a;
211 if (fromLeft) {
212 a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_in_left);
213 } else {
214 a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_in_right);
215 }
216
217 a.setInterpolator(new DecelerateInterpolator());
218 a.setStartTime(currentAnimationTimeMillis());
219 return a;
220 }
221
222 /**
223 * Make an animation for objects becoming invisible. Uses a slide and fade
224 * effect.
225 *
226 * @param c Context for loading resources
227 * @param toRight is the object to be animated exiting to the right
228 * @return The new animation
229 */
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700230 public static Animation makeOutAnimation(Context c, boolean toRight) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 Animation a;
232 if (toRight) {
233 a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_out_right);
234 } else {
235 a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_out_left);
236 }
237
238 a.setInterpolator(new AccelerateInterpolator());
239 a.setStartTime(currentAnimationTimeMillis());
240 return a;
241 }
242
243
244 /**
245 * Make an animation for objects becoming visible. Uses a slide up and fade
246 * effect.
247 *
248 * @param c Context for loading resources
249 * @return The new animation
250 */
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700251 public static Animation makeInChildBottomAnimation(Context c) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 Animation a;
253 a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_in_child_bottom);
254 a.setInterpolator(new AccelerateInterpolator());
255 a.setStartTime(currentAnimationTimeMillis());
256 return a;
257 }
258
259 /**
260 * Loads an {@link Interpolator} object from a resource
261 *
262 * @param context Application context used to access resources
263 * @param id The resource id of the animation to load
264 * @return The animation object reference by the specified id
265 * @throws NotFoundException
266 */
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700267 public static Interpolator loadInterpolator(Context context, int id) throws NotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 XmlResourceParser parser = null;
269 try {
270 parser = context.getResources().getAnimation(id);
271 return createInterpolatorFromXml(context, parser);
272 } catch (XmlPullParserException ex) {
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700273 NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
274 Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 rnf.initCause(ex);
276 throw rnf;
277 } catch (IOException ex) {
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700278 NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
279 Integer.toHexString(id));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 rnf.initCause(ex);
281 throw rnf;
282 } finally {
283 if (parser != null) parser.close();
284 }
285
286 }
287
288 private static Interpolator createInterpolatorFromXml(Context c, XmlPullParser parser)
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700289 throws XmlPullParserException, IOException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290
291 Interpolator interpolator = null;
292
293 // Make sure we are on a start tag.
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700294 int type;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295 int depth = parser.getDepth();
296
297 while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
298 && type != XmlPullParser.END_DOCUMENT) {
299
300 if (type != XmlPullParser.START_TAG) {
301 continue;
302 }
303
304 AttributeSet attrs = Xml.asAttributeSet(parser);
305
306 String name = parser.getName();
307
308
309 if (name.equals("linearInterpolator")) {
310 interpolator = new LinearInterpolator(c, attrs);
311 } else if (name.equals("accelerateInterpolator")) {
312 interpolator = new AccelerateInterpolator(c, attrs);
313 } else if (name.equals("decelerateInterpolator")) {
314 interpolator = new DecelerateInterpolator(c, attrs);
315 } else if (name.equals("accelerateDecelerateInterpolator")) {
316 interpolator = new AccelerateDecelerateInterpolator(c, attrs);
317 } else if (name.equals("cycleInterpolator")) {
318 interpolator = new CycleInterpolator(c, attrs);
Jean-Baptiste Queru8b066282009-03-25 15:05:51 -0700319 } else if (name.equals("anticipateInterpolator")) {
320 interpolator = new AnticipateInterpolator(c, attrs);
321 } else if (name.equals("overshootInterpolator")) {
322 interpolator = new OvershootInterpolator(c, attrs);
323 } else if (name.equals("anticipateOvershootInterpolator")) {
324 interpolator = new AnticipateOvershootInterpolator(c, attrs);
325 } else if (name.equals("bounceInterpolator")) {
326 interpolator = new BounceInterpolator(c, attrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 } else {
328 throw new RuntimeException("Unknown interpolator name: " + parser.getName());
329 }
330
331 }
332
333 return interpolator;
334
335 }
336}