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