12ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka/*
22ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka * Copyright (C) 2012 The Android Open Source Project
32ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka *
42ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka * Licensed under the Apache License, Version 2.0 (the "License");
52ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka * you may not use this file except in compliance with the License.
62ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka * You may obtain a copy of the License at
72ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka *
82ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka *      http://www.apache.org/licenses/LICENSE-2.0
92ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka *
102ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka * Unless required by applicable law or agreed to in writing, software
112ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka * distributed under the License is distributed on an "AS IS" BASIS,
122ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka * See the License for the specific language governing permissions and
142ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka * limitations under the License.
152ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka */
162ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka
17325dc23624160689e59fbac708cf6f222b20d025Daniel Sandlerpackage com.android.launcher3;
182ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka
192ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurkaimport android.animation.Animator;
202ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurkaimport android.animation.AnimatorSet;
212ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurkaimport android.animation.ObjectAnimator;
222ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurkaimport android.animation.PropertyValuesHolder;
232ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurkaimport android.animation.ValueAnimator;
24f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurkaimport android.view.View;
25f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurkaimport android.view.ViewTreeObserver;
262ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka
272ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurkaimport java.util.HashSet;
287c70d64d4c814e3d48b69aa4d9daf0717d71bff5Michael Jurkaimport java.util.WeakHashMap;
292ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka
302ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurkapublic class LauncherAnimUtils {
317c70d64d4c814e3d48b69aa4d9daf0717d71bff5Michael Jurka    static WeakHashMap<Animator, Object> sAnimators = new WeakHashMap<Animator, Object>();
32def8e655543384a2837b769d0bc43cdc252cbc53Michael Jurka    static Animator.AnimatorListener sEndAnimListener = new Animator.AnimatorListener() {
332ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        public void onAnimationStart(Animator animation) {
347c70d64d4c814e3d48b69aa4d9daf0717d71bff5Michael Jurka            sAnimators.put(animation, null);
352ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        }
362ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka
372ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        public void onAnimationRepeat(Animator animation) {
382ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        }
392ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka
402ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        public void onAnimationEnd(Animator animation) {
412ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka            sAnimators.remove(animation);
422ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        }
432ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka
442ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        public void onAnimationCancel(Animator animation) {
452ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka            sAnimators.remove(animation);
462ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        }
472ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka    };
482ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka
492ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka    public static void cancelOnDestroyActivity(Animator a) {
50def8e655543384a2837b769d0bc43cdc252cbc53Michael Jurka        a.addListener(sEndAnimListener);
512ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka    }
522ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka
53f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka    // Helper method. Assumes a draw is pending, and that if the animation's duration is 0
54f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka    // it should be cancelled
55f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka    public static void startAnimationAfterNextDraw(final Animator animator, final View view) {
56df96add095c82f9083f75305d8fa155c8192a4e6Michael Jurka        view.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
57df96add095c82f9083f75305d8fa155c8192a4e6Michael Jurka                private boolean mStarted = false;
58f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka                public void onDraw() {
59df96add095c82f9083f75305d8fa155c8192a4e6Michael Jurka                    if (mStarted) return;
60df96add095c82f9083f75305d8fa155c8192a4e6Michael Jurka                    mStarted = true;
61f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka                    // Use this as a signal that the animation was cancelled
62f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka                    if (animator.getDuration() == 0) {
63f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka                        return;
64f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka                    }
65f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka                    animator.start();
66df96add095c82f9083f75305d8fa155c8192a4e6Michael Jurka
67df96add095c82f9083f75305d8fa155c8192a4e6Michael Jurka                    final ViewTreeObserver.OnDrawListener listener = this;
68df96add095c82f9083f75305d8fa155c8192a4e6Michael Jurka                    view.post(new Runnable() {
69df96add095c82f9083f75305d8fa155c8192a4e6Michael Jurka                            public void run() {
70df96add095c82f9083f75305d8fa155c8192a4e6Michael Jurka                                view.getViewTreeObserver().removeOnDrawListener(listener);
71df96add095c82f9083f75305d8fa155c8192a4e6Michael Jurka                            }
72df96add095c82f9083f75305d8fa155c8192a4e6Michael Jurka                        });
73f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka                }
74f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka            });
75f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka    }
76f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka
772ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka    public static void onDestroyActivity() {
787c70d64d4c814e3d48b69aa4d9daf0717d71bff5Michael Jurka        HashSet<Animator> animators = new HashSet<Animator>(sAnimators.keySet());
7915ba53a54c8b319e3ccdffa586fab1cfcd8971e5Winson Chung        for (Animator a : animators) {
802ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka            if (a.isRunning()) {
812ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka                a.cancel();
822ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka            }
837c70d64d4c814e3d48b69aa4d9daf0717d71bff5Michael Jurka            sAnimators.remove(a);
842ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        }
852ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka    }
862ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka
872ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka    public static AnimatorSet createAnimatorSet() {
882ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        AnimatorSet anim = new AnimatorSet();
892ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        cancelOnDestroyActivity(anim);
902ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        return anim;
912ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka    }
922ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka
93f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka    public static ValueAnimator ofFloat(View target, float... values) {
942ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        ValueAnimator anim = new ValueAnimator();
952ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        anim.setFloatValues(values);
962ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        cancelOnDestroyActivity(anim);
972ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        return anim;
982ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka    }
992ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka
100f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka    public static ObjectAnimator ofFloat(View target, String propertyName, float... values) {
1012ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        ObjectAnimator anim = new ObjectAnimator();
1022ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        anim.setTarget(target);
1032ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        anim.setPropertyName(propertyName);
1042ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        anim.setFloatValues(values);
1052ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        cancelOnDestroyActivity(anim);
106f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka        new FirstFrameAnimatorHelper(anim, target);
1072ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        return anim;
1082ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka    }
1092ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka
110f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka    public static ObjectAnimator ofPropertyValuesHolder(View target,
1112ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka            PropertyValuesHolder... values) {
1122ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        ObjectAnimator anim = new ObjectAnimator();
1132ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        anim.setTarget(target);
1142ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        anim.setValues(values);
1152ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        cancelOnDestroyActivity(anim);
116f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka        new FirstFrameAnimatorHelper(anim, target);
117f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka        return anim;
118f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka    }
119f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka
120f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka    public static ObjectAnimator ofPropertyValuesHolder(Object target,
121f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka            View view, PropertyValuesHolder... values) {
122f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka        ObjectAnimator anim = new ObjectAnimator();
123f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka        anim.setTarget(target);
124f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka        anim.setValues(values);
125f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka        cancelOnDestroyActivity(anim);
126f1ad608c28c79c8e9b83d83ce9154f1b7284f412Michael Jurka        new FirstFrameAnimatorHelper(anim, view);
1272ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka        return anim;
1282ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka    }
1292ecf995e0d2d55eb71d03f7230ca87270872d1a3Michael Jurka}
130