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