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