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