1/* 2 * Copyright (C) 2012 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.launcher3; 18 19import android.animation.Animator; 20import android.animation.AnimatorSet; 21import android.animation.ObjectAnimator; 22import android.animation.PropertyValuesHolder; 23import android.animation.ValueAnimator; 24import android.annotation.TargetApi; 25import android.os.Build; 26import android.view.View; 27import android.view.ViewAnimationUtils; 28import android.view.ViewTreeObserver; 29 30import com.android.launcher3.util.UiThreadCircularReveal; 31 32import java.util.HashSet; 33import java.util.WeakHashMap; 34 35public class LauncherAnimUtils { 36 static WeakHashMap<Animator, Object> sAnimators = new WeakHashMap<Animator, Object>(); 37 static Animator.AnimatorListener sEndAnimListener = new Animator.AnimatorListener() { 38 public void onAnimationStart(Animator animation) { 39 sAnimators.put(animation, null); 40 } 41 42 public void onAnimationRepeat(Animator animation) { 43 } 44 45 public void onAnimationEnd(Animator animation) { 46 sAnimators.remove(animation); 47 } 48 49 public void onAnimationCancel(Animator animation) { 50 sAnimators.remove(animation); 51 } 52 }; 53 54 public static void cancelOnDestroyActivity(Animator a) { 55 a.addListener(sEndAnimListener); 56 } 57 58 // Helper method. Assumes a draw is pending, and that if the animation's duration is 0 59 // it should be cancelled 60 public static void startAnimationAfterNextDraw(final Animator animator, final View view) { 61 view.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() { 62 private boolean mStarted = false; 63 public void onDraw() { 64 if (mStarted) return; 65 mStarted = true; 66 // Use this as a signal that the animation was cancelled 67 if (animator.getDuration() == 0) { 68 return; 69 } 70 animator.start(); 71 72 final ViewTreeObserver.OnDrawListener listener = this; 73 view.post(new Runnable() { 74 public void run() { 75 view.getViewTreeObserver().removeOnDrawListener(listener); 76 } 77 }); 78 } 79 }); 80 } 81 82 public static void onDestroyActivity() { 83 HashSet<Animator> animators = new HashSet<Animator>(sAnimators.keySet()); 84 for (Animator a : animators) { 85 if (a.isRunning()) { 86 a.cancel(); 87 } 88 sAnimators.remove(a); 89 } 90 } 91 92 public static AnimatorSet createAnimatorSet() { 93 AnimatorSet anim = new AnimatorSet(); 94 cancelOnDestroyActivity(anim); 95 return anim; 96 } 97 98 public static ValueAnimator ofFloat(View target, float... values) { 99 ValueAnimator anim = new ValueAnimator(); 100 anim.setFloatValues(values); 101 cancelOnDestroyActivity(anim); 102 return anim; 103 } 104 105 public static ObjectAnimator ofFloat(View target, String propertyName, float... values) { 106 ObjectAnimator anim = new ObjectAnimator(); 107 anim.setTarget(target); 108 anim.setPropertyName(propertyName); 109 anim.setFloatValues(values); 110 cancelOnDestroyActivity(anim); 111 new FirstFrameAnimatorHelper(anim, target); 112 return anim; 113 } 114 115 public static ObjectAnimator ofPropertyValuesHolder(View target, 116 PropertyValuesHolder... values) { 117 ObjectAnimator anim = new ObjectAnimator(); 118 anim.setTarget(target); 119 anim.setValues(values); 120 cancelOnDestroyActivity(anim); 121 new FirstFrameAnimatorHelper(anim, target); 122 return anim; 123 } 124 125 public static ObjectAnimator ofPropertyValuesHolder(Object target, 126 View view, PropertyValuesHolder... values) { 127 ObjectAnimator anim = new ObjectAnimator(); 128 anim.setTarget(target); 129 anim.setValues(values); 130 cancelOnDestroyActivity(anim); 131 new FirstFrameAnimatorHelper(anim, view); 132 return anim; 133 } 134 135 @TargetApi(Build.VERSION_CODES.LOLLIPOP) 136 public static ValueAnimator createCircularReveal(View view, int centerX, 137 int centerY, float startRadius, float endRadius) { 138 ValueAnimator anim = UiThreadCircularReveal.createCircularReveal(view, centerX, 139 centerY, startRadius, endRadius); 140 new FirstFrameAnimatorHelper(anim, view); 141 return anim; 142 } 143} 144