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