Home | History | Annotate | Download | only in launcher3
      1 /*
      2  * Copyright (C) 2012 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.launcher3;
     18 
     19 import android.animation.Animator;
     20 import android.animation.AnimatorSet;
     21 import android.animation.ObjectAnimator;
     22 import android.animation.PropertyValuesHolder;
     23 import android.animation.ValueAnimator;
     24 import android.graphics.drawable.Drawable;
     25 import android.util.Property;
     26 import android.view.View;
     27 import android.view.ViewTreeObserver;
     28 
     29 import java.util.HashSet;
     30 import java.util.WeakHashMap;
     31 
     32 public class LauncherAnimUtils {
     33     /**
     34      * Durations for various state animations. These are not defined in resources to allow
     35      * easier access from static classes and enums
     36      */
     37     public static final int ALL_APPS_TRANSITION_MS = 320;
     38     public static final int OVERVIEW_TRANSITION_MS = 250;
     39     public static final int SPRING_LOADED_TRANSITION_MS = 150;
     40     public static final int SPRING_LOADED_EXIT_DELAY = 500;
     41 
     42     // The progress of an animation to all apps must be at least this far along to snap to all apps.
     43     public static final float MIN_PROGRESS_TO_ALL_APPS = 0.5f;
     44 
     45     static WeakHashMap<Animator, Object> sAnimators = new WeakHashMap<Animator, Object>();
     46     static Animator.AnimatorListener sEndAnimListener = new Animator.AnimatorListener() {
     47         public void onAnimationStart(Animator animation) {
     48             sAnimators.put(animation, null);
     49         }
     50 
     51         public void onAnimationRepeat(Animator animation) {
     52         }
     53 
     54         public void onAnimationEnd(Animator animation) {
     55             sAnimators.remove(animation);
     56         }
     57 
     58         public void onAnimationCancel(Animator animation) {
     59             sAnimators.remove(animation);
     60         }
     61     };
     62 
     63     public static void cancelOnDestroyActivity(Animator a) {
     64         a.addListener(sEndAnimListener);
     65     }
     66 
     67     // Helper method. Assumes a draw is pending, and that if the animation's duration is 0
     68     // it should be cancelled
     69     public static void startAnimationAfterNextDraw(final Animator animator, final View view) {
     70         view.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
     71             private boolean mStarted = false;
     72 
     73             public void onDraw() {
     74                 if (mStarted) return;
     75                 mStarted = true;
     76                 // Use this as a signal that the animation was cancelled
     77                 if (animator.getDuration() == 0) {
     78                     return;
     79                 }
     80                 animator.start();
     81 
     82                 final ViewTreeObserver.OnDrawListener listener = this;
     83                 view.post(new Runnable() {
     84                     public void run() {
     85                         view.getViewTreeObserver().removeOnDrawListener(listener);
     86                     }
     87                 });
     88             }
     89         });
     90     }
     91 
     92     public static void onDestroyActivity() {
     93         HashSet<Animator> animators = new HashSet<Animator>(sAnimators.keySet());
     94         for (Animator a : animators) {
     95             if (a.isRunning()) {
     96                 a.cancel();
     97             }
     98             sAnimators.remove(a);
     99         }
    100     }
    101 
    102     public static AnimatorSet createAnimatorSet() {
    103         AnimatorSet anim = new AnimatorSet();
    104         cancelOnDestroyActivity(anim);
    105         return anim;
    106     }
    107 
    108     public static ValueAnimator ofFloat(float... values) {
    109         ValueAnimator anim = new ValueAnimator();
    110         anim.setFloatValues(values);
    111         cancelOnDestroyActivity(anim);
    112         return anim;
    113     }
    114 
    115     public static ObjectAnimator ofFloat(View target, Property<View, Float> property,
    116             float... values) {
    117         ObjectAnimator anim = ObjectAnimator.ofFloat(target, property, values);
    118         cancelOnDestroyActivity(anim);
    119         new FirstFrameAnimatorHelper(anim, target);
    120         return anim;
    121     }
    122 
    123     public static ObjectAnimator ofViewAlphaAndScale(View target,
    124             float alpha, float scaleX, float scaleY) {
    125         return ofPropertyValuesHolder(target,
    126                 PropertyValuesHolder.ofFloat(View.ALPHA, alpha),
    127                 PropertyValuesHolder.ofFloat(View.SCALE_X, scaleX),
    128                 PropertyValuesHolder.ofFloat(View.SCALE_Y, scaleY));
    129     }
    130 
    131     public static ObjectAnimator ofPropertyValuesHolder(View target,
    132             PropertyValuesHolder... values) {
    133         return ofPropertyValuesHolder(target, target, values);
    134     }
    135 
    136     public static ObjectAnimator ofPropertyValuesHolder(Object target,
    137             View view, PropertyValuesHolder... values) {
    138         ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(target, values);
    139         cancelOnDestroyActivity(anim);
    140         new FirstFrameAnimatorHelper(anim, view);
    141         return anim;
    142     }
    143 
    144     public static final Property<Drawable, Integer> DRAWABLE_ALPHA =
    145             new Property<Drawable, Integer>(Integer.TYPE, "drawableAlpha") {
    146                 @Override
    147                 public Integer get(Drawable drawable) {
    148                     return drawable.getAlpha();
    149                 }
    150 
    151                 @Override
    152                 public void set(Drawable drawable, Integer alpha) {
    153                     drawable.setAlpha(alpha);
    154                 }
    155             };
    156 
    157     public static final Property<View, Float> SCALE_PROPERTY =
    158             new Property<View, Float>(Float.class, "scale") {
    159                 @Override
    160                 public Float get(View view) {
    161                     return view.getScaleX();
    162                 }
    163 
    164                 @Override
    165                 public void set(View view, Float scale) {
    166                     view.setScaleX(scale);
    167                     view.setScaleY(scale);
    168                 }
    169             };
    170 
    171     /** Increase the duration if we prevented the fling, as we are going against a high velocity. */
    172     public static int blockedFlingDurationFactor(float velocity) {
    173         return (int) Utilities.boundToRange(Math.abs(velocity) / 2, 2f, 6f);
    174     }
    175 }
    176