Home | History | Annotate | Download | only in animation
      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 {
     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