1 /* 2 * Copyright (C) 2014 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.deskclock; 18 19 import android.animation.ArgbEvaluator; 20 import android.animation.ObjectAnimator; 21 import android.animation.PropertyValuesHolder; 22 import android.animation.ValueAnimator; 23 import android.graphics.drawable.Drawable; 24 import android.support.v4.graphics.drawable.DrawableCompat; 25 import android.util.Property; 26 import android.view.View; 27 import android.view.animation.Interpolator; 28 import android.widget.ImageView; 29 30 import java.lang.reflect.InvocationTargetException; 31 import java.lang.reflect.Method; 32 33 public class AnimatorUtils { 34 35 public static final long ANIM_DURATION_SHORT = 266L; // 8/30 frames long 36 37 public static final Interpolator DECELERATE_ACCELERATE_INTERPOLATOR = new Interpolator() { 38 @Override 39 public float getInterpolation(float x) { 40 return 0.5f + 4.0f * (x - 0.5f) * (x - 0.5f) * (x - 0.5f); 41 } 42 }; 43 44 public static final Property<View, Integer> BACKGROUND_ALPHA = 45 new Property<View, Integer>(Integer.class, "background.alpha") { 46 @Override 47 public Integer get(View view) { 48 return view.getBackground().getAlpha(); 49 } 50 51 @Override 52 public void set(View view, Integer value) { 53 view.getBackground().setAlpha(value); 54 } 55 }; 56 57 public static final Property<ImageView, Integer> DRAWABLE_ALPHA = 58 new Property<ImageView, Integer>(Integer.class, "drawable.alpha") { 59 @Override 60 public Integer get(ImageView view) { 61 return view.getDrawable().getAlpha(); 62 } 63 64 @Override 65 public void set(ImageView view, Integer value) { 66 view.getDrawable().setAlpha(value); 67 } 68 }; 69 70 public static final Property<ImageView, Integer> DRAWABLE_TINT = 71 new Property<ImageView, Integer>(Integer.class, "drawable.tint") { 72 @Override 73 public Integer get(ImageView view) { 74 return null; 75 } 76 77 @Override 78 public void set(ImageView view, Integer value) { 79 // Ensure the drawable is wrapped using DrawableCompat. 80 final Drawable drawable = view.getDrawable(); 81 final Drawable wrappedDrawable = DrawableCompat.wrap(drawable); 82 if (wrappedDrawable != drawable) { 83 view.setImageDrawable(wrappedDrawable); 84 } 85 // Set the new tint value via DrawableCompat. 86 DrawableCompat.setTint(wrappedDrawable, value); 87 } 88 }; 89 90 public static final ArgbEvaluator ARGB_EVALUATOR = new ArgbEvaluator(); 91 92 private static Method sAnimateValue; 93 private static boolean sTryAnimateValue = true; 94 setAnimatedFraction(ValueAnimator animator, float fraction)95 public static void setAnimatedFraction(ValueAnimator animator, float fraction) { 96 if (Utils.isLMR1OrLater()) { 97 animator.setCurrentFraction(fraction); 98 return; 99 } 100 101 if (sTryAnimateValue) { 102 // try to set the animated fraction directly so that it isn't affected by the 103 // internal animator scale or time (b/17938711) 104 try { 105 if (sAnimateValue == null) { 106 sAnimateValue = ValueAnimator.class 107 .getDeclaredMethod("animateValue", float.class); 108 sAnimateValue.setAccessible(true); 109 } 110 111 sAnimateValue.invoke(animator, fraction); 112 return; 113 } catch (NoSuchMethodException | InvocationTargetException 114 | IllegalAccessException e) { 115 // something went wrong, don't try that again 116 LogUtils.e("Unable to use animateValue directly", e); 117 sTryAnimateValue = false; 118 } 119 } 120 121 // if that doesn't work then just fall back to setting the current play time 122 animator.setCurrentPlayTime(Math.round(fraction * animator.getDuration())); 123 } 124 reverse(ValueAnimator... animators)125 public static void reverse(ValueAnimator... animators) { 126 for (ValueAnimator animator : animators) { 127 final float fraction = animator.getAnimatedFraction(); 128 if (fraction > 0.0f) { 129 animator.reverse(); 130 setAnimatedFraction(animator, 1.0f - fraction); 131 } 132 } 133 } 134 cancel(ValueAnimator... animators)135 public static void cancel(ValueAnimator... animators) { 136 for (ValueAnimator animator : animators) { 137 animator.cancel(); 138 } 139 } 140 getScaleAnimator(View view, float... values)141 public static ValueAnimator getScaleAnimator(View view, float... values) { 142 return ObjectAnimator.ofPropertyValuesHolder(view, 143 PropertyValuesHolder.ofFloat(View.SCALE_X, values), 144 PropertyValuesHolder.ofFloat(View.SCALE_Y, values)); 145 } 146 } 147