OSDN Git Service

DO NOT MERGE. Grant MMS Uri permissions as the calling UID.
[android-x86/frameworks-base.git] / core / java / android / view / animation / AnimationUtils.java
1 /*
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
17 package android.view.animation;
18
19 import org.xmlpull.v1.XmlPullParser;
20 import org.xmlpull.v1.XmlPullParserException;
21
22 import android.annotation.AnimRes;
23 import android.annotation.InterpolatorRes;
24 import android.content.Context;
25 import android.content.res.Resources;
26 import android.content.res.Resources.Theme;
27 import android.content.res.XmlResourceParser;
28 import android.content.res.Resources.NotFoundException;
29 import android.util.AttributeSet;
30 import android.util.Xml;
31 import android.os.SystemClock;
32
33 import java.io.IOException;
34
35 /**
36  * Defines common utilities for working with animations.
37  *
38  */
39 public class AnimationUtils {
40
41     /**
42      * These flags are used when parsing AnimatorSet objects
43      */
44     private static final int TOGETHER = 0;
45     private static final int SEQUENTIALLY = 1;
46
47
48     /**
49      * Returns the current animation time in milliseconds. This time should be used when invoking
50      * {@link Animation#setStartTime(long)}. Refer to {@link android.os.SystemClock} for more
51      * information about the different available clocks. The clock used by this method is
52      * <em>not</em> the "wall" clock (it is not {@link System#currentTimeMillis}).
53      *
54      * @return the current animation time in milliseconds
55      *
56      * @see android.os.SystemClock
57      */
58     public static long currentAnimationTimeMillis() {
59         return SystemClock.uptimeMillis();
60     }
61
62     /**
63      * Loads an {@link Animation} object from a resource
64      *
65      * @param context Application context used to access resources
66      * @param id The resource id of the animation to load
67      * @return The animation object reference by the specified id
68      * @throws NotFoundException when the animation cannot be loaded
69      */
70     public static Animation loadAnimation(Context context, @AnimRes int id)
71             throws NotFoundException {
72
73         XmlResourceParser parser = null;
74         try {
75             parser = context.getResources().getAnimation(id);
76             return createAnimationFromXml(context, parser);
77         } catch (XmlPullParserException ex) {
78             NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
79                     Integer.toHexString(id));
80             rnf.initCause(ex);
81             throw rnf;
82         } catch (IOException ex) {
83             NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
84                     Integer.toHexString(id));
85             rnf.initCause(ex);
86             throw rnf;
87         } finally {
88             if (parser != null) parser.close();
89         }
90     }
91
92     private static Animation createAnimationFromXml(Context c, XmlPullParser parser)
93             throws XmlPullParserException, IOException {
94
95         return createAnimationFromXml(c, parser, null, Xml.asAttributeSet(parser));
96     }
97
98     private static Animation createAnimationFromXml(Context c, XmlPullParser parser,
99             AnimationSet parent, AttributeSet attrs) throws XmlPullParserException, IOException {
100
101         Animation anim = null;
102
103         // Make sure we are on a start tag.
104         int type;
105         int depth = parser.getDepth();
106
107         while (((type=parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
108                && type != XmlPullParser.END_DOCUMENT) {
109
110             if (type != XmlPullParser.START_TAG) {
111                 continue;
112             }
113
114             String  name = parser.getName();
115
116             if (name.equals("set")) {
117                 anim = new AnimationSet(c, attrs);
118                 createAnimationFromXml(c, parser, (AnimationSet)anim, attrs);
119             } else if (name.equals("alpha")) {
120                 anim = new AlphaAnimation(c, attrs);
121             } else if (name.equals("scale")) {
122                 anim = new ScaleAnimation(c, attrs);
123             }  else if (name.equals("rotate")) {
124                 anim = new RotateAnimation(c, attrs);
125             }  else if (name.equals("translate")) {
126                 anim = new TranslateAnimation(c, attrs);
127             } else {
128                 throw new RuntimeException("Unknown animation name: " + parser.getName());
129             }
130
131             if (parent != null) {
132                 parent.addAnimation(anim);
133             }
134         }
135
136         return anim;
137
138     }
139
140     /**
141      * Loads a {@link LayoutAnimationController} object from a resource
142      *
143      * @param context Application context used to access resources
144      * @param id The resource id of the animation to load
145      * @return The animation object reference by the specified id
146      * @throws NotFoundException when the layout animation controller cannot be loaded
147      */
148     public static LayoutAnimationController loadLayoutAnimation(Context context, @AnimRes int id)
149             throws NotFoundException {
150
151         XmlResourceParser parser = null;
152         try {
153             parser = context.getResources().getAnimation(id);
154             return createLayoutAnimationFromXml(context, parser);
155         } catch (XmlPullParserException ex) {
156             NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
157                     Integer.toHexString(id));
158             rnf.initCause(ex);
159             throw rnf;
160         } catch (IOException ex) {
161             NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
162                     Integer.toHexString(id));
163             rnf.initCause(ex);
164             throw rnf;
165         } finally {
166             if (parser != null) parser.close();
167         }
168     }
169
170     private static LayoutAnimationController createLayoutAnimationFromXml(Context c,
171             XmlPullParser parser) throws XmlPullParserException, IOException {
172
173         return createLayoutAnimationFromXml(c, parser, Xml.asAttributeSet(parser));
174     }
175
176     private static LayoutAnimationController createLayoutAnimationFromXml(Context c,
177             XmlPullParser parser, AttributeSet attrs) throws XmlPullParserException, IOException {
178
179         LayoutAnimationController controller = null;
180
181         int type;
182         int depth = parser.getDepth();
183
184         while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
185                 && type != XmlPullParser.END_DOCUMENT) {
186
187             if (type != XmlPullParser.START_TAG) {
188                 continue;
189             }
190
191             String name = parser.getName();
192
193             if ("layoutAnimation".equals(name)) {
194                 controller = new LayoutAnimationController(c, attrs);
195             } else if ("gridLayoutAnimation".equals(name)) {
196                 controller = new GridLayoutAnimationController(c, attrs);
197             } else {
198                 throw new RuntimeException("Unknown layout animation name: " + name);
199             }
200         }
201
202         return controller;
203     }
204
205     /**
206      * Make an animation for objects becoming visible. Uses a slide and fade
207      * effect.
208      *
209      * @param c Context for loading resources
210      * @param fromLeft is the object to be animated coming from the left
211      * @return The new animation
212      */
213     public static Animation makeInAnimation(Context c, boolean fromLeft) {
214         Animation a;
215         if (fromLeft) {
216             a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_in_left);
217         } else {
218             a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_in_right);
219         }
220
221         a.setInterpolator(new DecelerateInterpolator());
222         a.setStartTime(currentAnimationTimeMillis());
223         return a;
224     }
225
226     /**
227      * Make an animation for objects becoming invisible. Uses a slide and fade
228      * effect.
229      *
230      * @param c Context for loading resources
231      * @param toRight is the object to be animated exiting to the right
232      * @return The new animation
233      */
234     public static Animation makeOutAnimation(Context c, boolean toRight) {
235         Animation a;
236         if (toRight) {
237             a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_out_right);
238         } else {
239             a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_out_left);
240         }
241
242         a.setInterpolator(new AccelerateInterpolator());
243         a.setStartTime(currentAnimationTimeMillis());
244         return a;
245     }
246
247
248     /**
249      * Make an animation for objects becoming visible. Uses a slide up and fade
250      * effect.
251      *
252      * @param c Context for loading resources
253      * @return The new animation
254      */
255     public static Animation makeInChildBottomAnimation(Context c) {
256         Animation a;
257         a = AnimationUtils.loadAnimation(c, com.android.internal.R.anim.slide_in_child_bottom);
258         a.setInterpolator(new AccelerateInterpolator());
259         a.setStartTime(currentAnimationTimeMillis());
260         return a;
261     }
262
263     /**
264      * Loads an {@link Interpolator} object from a resource
265      *
266      * @param context Application context used to access resources
267      * @param id The resource id of the animation to load
268      * @return The animation object reference by the specified id
269      * @throws NotFoundException
270      */
271     public static Interpolator loadInterpolator(Context context, @AnimRes @InterpolatorRes int id)
272             throws NotFoundException {
273         XmlResourceParser parser = null;
274         try {
275             parser = context.getResources().getAnimation(id);
276             return createInterpolatorFromXml(context.getResources(), context.getTheme(), parser);
277         } catch (XmlPullParserException ex) {
278             NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
279                     Integer.toHexString(id));
280             rnf.initCause(ex);
281             throw rnf;
282         } catch (IOException ex) {
283             NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
284                     Integer.toHexString(id));
285             rnf.initCause(ex);
286             throw rnf;
287         } finally {
288             if (parser != null) parser.close();
289         }
290
291     }
292
293     /**
294      * Loads an {@link Interpolator} object from a resource
295      *
296      * @param res The resources
297      * @param id The resource id of the animation to load
298      * @return The interpolator object reference by the specified id
299      * @throws NotFoundException
300      * @hide
301      */
302     public static Interpolator loadInterpolator(Resources res, Theme theme, int id) throws NotFoundException {
303         XmlResourceParser parser = null;
304         try {
305             parser = res.getAnimation(id);
306             return createInterpolatorFromXml(res, theme, parser);
307         } catch (XmlPullParserException ex) {
308             NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
309                     Integer.toHexString(id));
310             rnf.initCause(ex);
311             throw rnf;
312         } catch (IOException ex) {
313             NotFoundException rnf = new NotFoundException("Can't load animation resource ID #0x" +
314                     Integer.toHexString(id));
315             rnf.initCause(ex);
316             throw rnf;
317         } finally {
318             if (parser != null)
319                 parser.close();
320         }
321
322     }
323
324     private static Interpolator createInterpolatorFromXml(Resources res, Theme theme, XmlPullParser parser)
325             throws XmlPullParserException, IOException {
326
327         BaseInterpolator interpolator = null;
328
329         // Make sure we are on a start tag.
330         int type;
331         int depth = parser.getDepth();
332
333         while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
334                 && type != XmlPullParser.END_DOCUMENT) {
335
336             if (type != XmlPullParser.START_TAG) {
337                 continue;
338             }
339
340             AttributeSet attrs = Xml.asAttributeSet(parser);
341
342             String name = parser.getName();
343
344             if (name.equals("linearInterpolator")) {
345                 interpolator = new LinearInterpolator();
346             } else if (name.equals("accelerateInterpolator")) {
347                 interpolator = new AccelerateInterpolator(res, theme, attrs);
348             } else if (name.equals("decelerateInterpolator")) {
349                 interpolator = new DecelerateInterpolator(res, theme, attrs);
350             } else if (name.equals("accelerateDecelerateInterpolator")) {
351                 interpolator = new AccelerateDecelerateInterpolator();
352             } else if (name.equals("cycleInterpolator")) {
353                 interpolator = new CycleInterpolator(res, theme, attrs);
354             } else if (name.equals("anticipateInterpolator")) {
355                 interpolator = new AnticipateInterpolator(res, theme, attrs);
356             } else if (name.equals("overshootInterpolator")) {
357                 interpolator = new OvershootInterpolator(res, theme, attrs);
358             } else if (name.equals("anticipateOvershootInterpolator")) {
359                 interpolator = new AnticipateOvershootInterpolator(res, theme, attrs);
360             } else if (name.equals("bounceInterpolator")) {
361                 interpolator = new BounceInterpolator();
362             } else if (name.equals("pathInterpolator")) {
363                 interpolator = new PathInterpolator(res, theme, attrs);
364             } else {
365                 throw new RuntimeException("Unknown interpolator name: " + parser.getName());
366             }
367         }
368         return interpolator;
369     }
370 }