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 17 package com.android.launcher3; 18 19 import android.animation.Animator; 20 import android.animation.AnimatorSet; 21 import android.animation.ObjectAnimator; 22 import android.animation.PropertyValuesHolder; 23 import android.animation.ValueAnimator; 24 import android.annotation.TargetApi; 25 import android.os.Build; 26 import android.view.View; 27 import android.view.ViewTreeObserver; 28 29 import com.android.launcher3.util.UiThreadCircularReveal; 30 31 import java.util.HashSet; 32 import java.util.WeakHashMap; 33 34 public class LauncherAnimUtils { 35 static WeakHashMap<Animator, Object> sAnimators = new WeakHashMap<Animator, Object>(); 36 static Animator.AnimatorListener sEndAnimListener = new Animator.AnimatorListener() { 37 public void onAnimationStart(Animator animation) { 38 sAnimators.put(animation, null); 39 } 40 41 public void onAnimationRepeat(Animator animation) { 42 } 43 44 public void onAnimationEnd(Animator animation) { 45 sAnimators.remove(animation); 46 } 47 48 public void onAnimationCancel(Animator animation) { 49 sAnimators.remove(animation); 50 } 51 }; 52 cancelOnDestroyActivity(Animator a)53 public static void cancelOnDestroyActivity(Animator a) { 54 a.addListener(sEndAnimListener); 55 } 56 57 // Helper method. Assumes a draw is pending, and that if the animation's duration is 0 58 // it should be cancelled startAnimationAfterNextDraw(final Animator animator, final View view)59 public static void startAnimationAfterNextDraw(final Animator animator, final View view) { 60 view.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() { 61 private boolean mStarted = false; 62 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 onDestroyActivity()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 createAnimatorSet()92 public static AnimatorSet createAnimatorSet() { 93 AnimatorSet anim = new AnimatorSet(); 94 cancelOnDestroyActivity(anim); 95 return anim; 96 } 97 ofFloat(View target, float... values)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 ofFloat(View target, String propertyName, float... values)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 ofPropertyValuesHolder(View target, PropertyValuesHolder... values)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 ofPropertyValuesHolder(Object target, View view, PropertyValuesHolder... values)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) createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius)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