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.phone.common.animation; 18 19import android.animation.Animator; 20import android.animation.AnimatorListenerAdapter; 21import android.animation.ValueAnimator; 22import android.view.View; 23import android.view.ViewPropertyAnimator; 24import android.view.animation.Interpolator; 25import android.view.animation.PathInterpolator; 26 27import java.lang.Float; 28 29public 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 { 38 public void onAnimationEnd() {} 39 public void onAnimationCancel() {} 40 } 41 42 public static void crossFadeViews(View fadeIn, View fadeOut, int duration) { 43 fadeIn(fadeIn, duration); 44 fadeOut(fadeOut, duration); 45 } 46 47 public static void fadeOut(View fadeOut, int duration) { 48 fadeOut(fadeOut, duration, null); 49 } 50 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 80 public static void fadeIn(View fadeIn, int durationMs) { 81 fadeIn(fadeIn, durationMs, NO_DELAY, null); 82 } 83 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 */ 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 */ 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 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 */ 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