Tweener.java revision 70832a3d77d90f09fb7ba27612c9cbec6a92abe6
1/*
2 * Copyright (C) 2011 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 com.android.internal.widget.multiwaveview;
18
19import java.util.ArrayList;
20import java.util.HashMap;
21
22import android.animation.Animator.AnimatorListener;
23import android.animation.ObjectAnimator;
24import android.animation.PropertyValuesHolder;
25import android.animation.TimeInterpolator;
26import android.animation.ValueAnimator.AnimatorUpdateListener;
27
28class Tweener {
29    private static final String TAG = "Tweener";
30
31    private Object object;
32    ObjectAnimator animator;
33    private static HashMap<Object, Tweener> sTweens = new HashMap<Object, Tweener>();
34
35    public Tweener(Object obj, ObjectAnimator anim) {
36        object = obj;
37        animator = anim;
38    }
39
40    public static Tweener to(Object object, long duration, Object... vars) {
41        long delay = 0;
42        AnimatorUpdateListener updateListener = null;
43        AnimatorListener listener = null;
44        TimeInterpolator interpolator = null;
45
46        // Iterate through arguments and discover properties to animate
47        ArrayList<PropertyValuesHolder> props = new ArrayList<PropertyValuesHolder>(vars.length/2);
48        for (int i = 0; i < vars.length; i+=2) {
49            if (!(vars[i] instanceof String)) {
50                throw new IllegalArgumentException("Key must be a string: " + vars[i]);
51            }
52            String key = (String) vars[i];
53            Object value = vars[i+1];
54            if ("simultaneousTween".equals(key)) {
55                // TODO
56            } else if ("ease".equals(key)) {
57                interpolator = (TimeInterpolator) value; // TODO: multiple interpolators?
58            } else if ("onUpdate".equals(key) || "onUpdateListener".equals(key)) {
59                updateListener = (AnimatorUpdateListener) value;
60            } else if ("onComplete".equals(key) || "onCompleteListener".equals(key)) {
61                listener = (AnimatorListener) value;
62            } else if ("delay".equals(key)) {
63                delay = ((Number) value).longValue();
64            } else if ("syncWith".equals(key)) {
65                // TODO
66            } else if (value instanceof float[]) {
67                props.add(PropertyValuesHolder.ofFloat(key,
68                        ((float[])value)[0], ((float[])value)[1]));
69            } else if (value instanceof Number) {
70                float floatValue = ((Number)value).floatValue();
71                props.add(PropertyValuesHolder.ofFloat(key, floatValue));
72            } else {
73                throw new IllegalArgumentException(
74                        "Bad argument for key \"" + key + "\" with value " + value.getClass());
75            }
76        }
77
78        // Re-use existing tween, if present
79        Tweener tween = sTweens.get(object);
80        if (tween == null) {
81            ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(object,
82                    props.toArray(new PropertyValuesHolder[props.size()]));
83            tween = new Tweener(object, anim);
84            sTweens.put(object, tween);
85        } else {
86            tween.animator.cancel();
87            replace(props, object);
88        }
89
90        if (interpolator != null) {
91            tween.animator.setInterpolator(interpolator);
92        }
93
94        // Update animation with properties discovered in loop above
95        tween.animator.setStartDelay(delay);
96        tween.animator.setDuration(duration);
97        if (updateListener != null) {
98            tween.animator.removeAllUpdateListeners(); // There should be only one
99            tween.animator.addUpdateListener(updateListener);
100        }
101        if (listener != null) {
102            tween.animator.removeAllListeners(); // There should be only one.
103            tween.animator.addListener(listener);
104        }
105        tween.animator.start();
106
107        return tween;
108    }
109
110    Tweener from(Object object, long duration, Object... vars) {
111        // TODO:  for v of vars
112        //            toVars[v] = object[v]
113        //            object[v] = vars[v]
114        return Tweener.to(object, duration, vars);
115    }
116
117    static void replace(ArrayList<PropertyValuesHolder> props, Object... args) {
118        for (final Object killobject : args) {
119            Tweener tween = sTweens.get(killobject);
120            if (tween != null) {
121                if (killobject == tween.object) {
122                    tween.animator.cancel();
123                    if (props != null) {
124                        tween.animator.setValues(
125                                props.toArray(new PropertyValuesHolder[props.size()]));
126                    } else {
127                        sTweens.remove(tween);
128                    }
129                }
130            }
131        }
132    }
133}
134