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 
     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 {
     42         public void onAnimationEnd() {}
     43         public void onAnimationCancel() {}
     44     }
     45 
     46     public static void crossFadeViews(View fadeIn, View fadeOut, int duration) {
     47         fadeIn(fadeIn, duration);
     48         fadeOut(fadeOut, duration);
     49     }
     50 
     51     public static void fadeOut(View fadeOut, int duration) {
     52         fadeOut(fadeOut, duration, null);
     53     }
     54 
     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 
     84     public static void fadeIn(View fadeIn, int durationMs) {
     85         fadeIn(fadeIn, durationMs, NO_DELAY, null);
     86     }
     87 
     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      */
    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      */
    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 
    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      */
    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