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.phone.common.animation; 18 19 import android.animation.Animator; 20 import android.animation.AnimatorListenerAdapter; 21 import android.animation.ValueAnimator; 22 import android.view.View; 23 import android.view.ViewPropertyAnimator; 24 import android.view.animation.Interpolator; 25 import android.view.animation.PathInterpolator; 26 27 import java.lang.Float; 28 29 public class AnimUtils { 30 public static final int DEFAULT_DURATION = -1; 31 public static final int NO_DELAY = 0; 32 33 public static final Interpolator EASE_IN = new PathInterpolator(0.0f, 0.0f, 0.2f, 1.0f); 34 public static final Interpolator EASE_OUT = new PathInterpolator(0.4f, 0.0f, 1.0f, 1.0f); 35 public static final Interpolator EASE_OUT_EASE_IN = new PathInterpolator(0.4f, 0, 0.2f, 1); 36 37 public static class AnimationCallback { onAnimationEnd()38 public void onAnimationEnd() {} onAnimationCancel()39 public void onAnimationCancel() {} 40 } 41 crossFadeViews(View fadeIn, View fadeOut, int duration)42 public static void crossFadeViews(View fadeIn, View fadeOut, int duration) { 43 fadeIn(fadeIn, duration); 44 fadeOut(fadeOut, duration); 45 } 46 fadeOut(View fadeOut, int duration)47 public static void fadeOut(View fadeOut, int duration) { 48 fadeOut(fadeOut, duration, null); 49 } 50 fadeOut(final View fadeOut, int durationMs, final AnimationCallback callback)51 public static void fadeOut(final View fadeOut, int durationMs, 52 final AnimationCallback callback) { 53 fadeOut.setAlpha(1); 54 final ViewPropertyAnimator animator = fadeOut.animate(); 55 animator.cancel(); 56 animator.alpha(0).withLayer().setListener(new AnimatorListenerAdapter() { 57 @Override 58 public void onAnimationEnd(Animator animation) { 59 fadeOut.setVisibility(View.GONE); 60 if (callback != null) { 61 callback.onAnimationEnd(); 62 } 63 } 64 65 @Override 66 public void onAnimationCancel(Animator animation) { 67 fadeOut.setVisibility(View.GONE); 68 fadeOut.setAlpha(0); 69 if (callback != null) { 70 callback.onAnimationCancel(); 71 } 72 } 73 }); 74 if (durationMs != DEFAULT_DURATION) { 75 animator.setDuration(durationMs); 76 } 77 animator.start(); 78 } 79 fadeIn(View fadeIn, int durationMs)80 public static void fadeIn(View fadeIn, int durationMs) { 81 fadeIn(fadeIn, durationMs, NO_DELAY, null); 82 } 83 fadeIn(final View fadeIn, int durationMs, int delay, final AnimationCallback callback)84 public static void fadeIn(final View fadeIn, int durationMs, int delay, 85 final AnimationCallback callback) { 86 fadeIn.setAlpha(0); 87 final ViewPropertyAnimator animator = fadeIn.animate(); 88 animator.cancel(); 89 90 animator.setStartDelay(delay); 91 animator.alpha(1).withLayer().setListener(new AnimatorListenerAdapter() { 92 @Override 93 public void onAnimationStart(Animator animation) { 94 fadeIn.setVisibility(View.VISIBLE); 95 } 96 97 @Override 98 public void onAnimationCancel(Animator animation) { 99 fadeIn.setAlpha(1); 100 if (callback != null) { 101 callback.onAnimationCancel(); 102 } 103 } 104 105 @Override 106 public void onAnimationEnd(Animator animation) { 107 if (callback != null) { 108 callback.onAnimationEnd(); 109 } 110 } 111 }); 112 if (durationMs != DEFAULT_DURATION) { 113 animator.setDuration(durationMs); 114 } 115 animator.start(); 116 } 117 118 /** 119 * Scales in the view from scale of 0 to actual dimensions. 120 * @param view The view to scale. 121 * @param durationMs The duration of the scaling in milliseconds. 122 * @param startDelayMs The delay to applying the scaling in milliseconds. 123 */ scaleIn(final View view, int durationMs, int startDelayMs)124 public static void scaleIn(final View view, int durationMs, int startDelayMs) { 125 AnimatorListenerAdapter listener = (new AnimatorListenerAdapter() { 126 @Override 127 public void onAnimationStart(Animator animation) { 128 view.setVisibility(View.VISIBLE); 129 } 130 131 @Override 132 public void onAnimationCancel(Animator animation) { 133 view.setScaleX(1); 134 view.setScaleY(1); 135 } 136 }); 137 scaleInternal(view, 0 /* startScaleValue */, 1 /* endScaleValue */, durationMs, 138 startDelayMs, listener, EASE_IN); 139 } 140 141 142 /** 143 * Scales out the view from actual dimensions to 0. 144 * @param view The view to scale. 145 * @param durationMs The duration of the scaling in milliseconds. 146 */ scaleOut(final View view, int durationMs)147 public static void scaleOut(final View view, int durationMs) { 148 AnimatorListenerAdapter listener = new AnimatorListenerAdapter() { 149 @Override 150 public void onAnimationEnd(Animator animation) { 151 view.setVisibility(View.GONE); 152 } 153 154 @Override 155 public void onAnimationCancel(Animator animation) { 156 view.setVisibility(View.GONE); 157 view.setScaleX(0); 158 view.setScaleY(0); 159 } 160 }; 161 162 scaleInternal(view, 1 /* startScaleValue */, 0 /* endScaleValue */, durationMs, 163 NO_DELAY, listener, EASE_OUT); 164 } 165 scaleInternal(final View view, int startScaleValue, int endScaleValue, int durationMs, int startDelay, AnimatorListenerAdapter listener, Interpolator interpolator)166 private static void scaleInternal(final View view, int startScaleValue, int endScaleValue, 167 int durationMs, int startDelay, AnimatorListenerAdapter listener, 168 Interpolator interpolator) { 169 view.setScaleX(startScaleValue); 170 view.setScaleY(startScaleValue); 171 172 final ViewPropertyAnimator animator = view.animate(); 173 animator.cancel(); 174 175 animator.setInterpolator(interpolator) 176 .scaleX(endScaleValue) 177 .scaleY(endScaleValue) 178 .setListener(listener) 179 .withLayer(); 180 181 if (durationMs != DEFAULT_DURATION) { 182 animator.setDuration(durationMs); 183 } 184 animator.setStartDelay(startDelay); 185 186 animator.start(); 187 } 188 189 /** 190 * Animates a view to the new specified dimensions. 191 * @param view The view to change the dimensions of. 192 * @param newWidth The new width of the view. 193 * @param newHeight The new height of the view. 194 */ changeDimensions(final View view, final int newWidth, final int newHeight)195 public static void changeDimensions(final View view, final int newWidth, final int newHeight) { 196 ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f); 197 198 final int oldWidth = view.getWidth(); 199 final int oldHeight = view.getHeight(); 200 final int deltaWidth = newWidth - oldWidth; 201 final int deltaHeight = newHeight - oldHeight; 202 203 animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 204 @Override 205 public void onAnimationUpdate(ValueAnimator animator) { 206 Float value = (Float) animator.getAnimatedValue(); 207 208 view.getLayoutParams().width = (int) (value * deltaWidth + oldWidth); 209 view.getLayoutParams().height = (int) (value * deltaHeight + oldHeight); 210 view.requestLayout(); 211 } 212 }); 213 animator.start(); 214 } 215 } 216