• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.keyguard;
18 
19 import android.content.Context;
20 import android.view.View;
21 import android.view.animation.AnimationUtils;
22 import android.view.animation.Interpolator;
23 
24 /**
25  * A class to make nice appear transitions for views in a tabular layout.
26  */
27 public class AppearAnimationUtils implements AppearAnimationCreator<View> {
28 
29     public static final long DEFAULT_APPEAR_DURATION = 220;
30 
31     private final Interpolator mInterpolator;
32     private final float mStartTranslation;
33     private final AppearAnimationProperties mProperties = new AppearAnimationProperties();
34     protected final float mDelayScale;
35     private final long mDuration;
36     protected boolean mScaleTranslationWithRow;
37     protected boolean mAppearing;
38 
AppearAnimationUtils(Context ctx)39     public AppearAnimationUtils(Context ctx) {
40         this(ctx, DEFAULT_APPEAR_DURATION,
41                 1.0f, 1.0f,
42                 AnimationUtils.loadInterpolator(ctx, android.R.interpolator.linear_out_slow_in));
43     }
44 
AppearAnimationUtils(Context ctx, long duration, float translationScaleFactor, float delayScaleFactor, Interpolator interpolator)45     public AppearAnimationUtils(Context ctx, long duration, float translationScaleFactor,
46             float delayScaleFactor, Interpolator interpolator) {
47         mInterpolator = interpolator;
48         mStartTranslation = ctx.getResources().getDimensionPixelOffset(
49                 R.dimen.appear_y_translation_start) * translationScaleFactor;
50         mDelayScale = delayScaleFactor;
51         mDuration = duration;
52         mScaleTranslationWithRow = false;
53         mAppearing = true;
54     }
55 
startAnimation(View[][] objects, final Runnable finishListener)56     public void startAnimation(View[][] objects, final Runnable finishListener) {
57         startAnimation(objects, finishListener, this);
58     }
59 
startAnimation(View[] objects, final Runnable finishListener)60     public void startAnimation(View[] objects, final Runnable finishListener) {
61         startAnimation(objects, finishListener, this);
62     }
63 
startAnimation(T[][] objects, final Runnable finishListener, AppearAnimationCreator<T> creator)64     public <T> void startAnimation(T[][] objects, final Runnable finishListener,
65             AppearAnimationCreator<T> creator) {
66         AppearAnimationProperties properties = getDelays(objects);
67         startAnimations(properties, objects, finishListener, creator);
68     }
69 
startAnimation(T[] objects, final Runnable finishListener, AppearAnimationCreator<T> creator)70     public <T> void startAnimation(T[] objects, final Runnable finishListener,
71             AppearAnimationCreator<T> creator) {
72         AppearAnimationProperties properties = getDelays(objects);
73         startAnimations(properties, objects, finishListener, creator);
74     }
75 
startAnimations(AppearAnimationProperties properties, T[] objects, final Runnable finishListener, AppearAnimationCreator<T> creator)76     private <T> void startAnimations(AppearAnimationProperties properties, T[] objects,
77             final Runnable finishListener, AppearAnimationCreator<T> creator) {
78         if (properties.maxDelayRowIndex == -1 || properties.maxDelayColIndex == -1) {
79             finishListener.run();
80             return;
81         }
82         for (int row = 0; row < properties.delays.length; row++) {
83             long[] columns = properties.delays[row];
84             long delay = columns[0];
85             Runnable endRunnable = null;
86             if (properties.maxDelayRowIndex == row && properties.maxDelayColIndex == 0) {
87                 endRunnable = finishListener;
88             }
89             creator.createAnimation(objects[row], delay, mDuration,
90                     mStartTranslation, true /* appearing */, mInterpolator, endRunnable);
91         }
92     }
93 
startAnimations(AppearAnimationProperties properties, T[][] objects, final Runnable finishListener, AppearAnimationCreator<T> creator)94     private <T> void startAnimations(AppearAnimationProperties properties, T[][] objects,
95             final Runnable finishListener, AppearAnimationCreator<T> creator) {
96         if (properties.maxDelayRowIndex == -1 || properties.maxDelayColIndex == -1) {
97             finishListener.run();
98             return;
99         }
100         for (int row = 0; row < properties.delays.length; row++) {
101             long[] columns = properties.delays[row];
102             float translation = mScaleTranslationWithRow
103                     ? (float) (Math.pow((properties.delays.length - row), 2)
104                     / properties.delays.length * mStartTranslation)
105                     : mStartTranslation;
106             for (int col = 0; col < columns.length; col++) {
107                 long delay = columns[col];
108                 Runnable endRunnable = null;
109                 if (properties.maxDelayRowIndex == row && properties.maxDelayColIndex == col) {
110                     endRunnable = finishListener;
111                 }
112                 creator.createAnimation(objects[row][col], delay, mDuration,
113                         mAppearing ? translation : -translation,
114                         mAppearing, mInterpolator, endRunnable);
115             }
116         }
117     }
118 
getDelays(T[] items)119     private <T> AppearAnimationProperties getDelays(T[] items) {
120         long maxDelay = -1;
121         mProperties.maxDelayColIndex = -1;
122         mProperties.maxDelayRowIndex = -1;
123         mProperties.delays = new long[items.length][];
124         for (int row = 0; row < items.length; row++) {
125             mProperties.delays[row] = new long[1];
126             long delay = calculateDelay(row, 0);
127             mProperties.delays[row][0] = delay;
128             if (items[row] != null && delay > maxDelay) {
129                 maxDelay = delay;
130                 mProperties.maxDelayColIndex = 0;
131                 mProperties.maxDelayRowIndex = row;
132             }
133         }
134         return mProperties;
135     }
136 
getDelays(T[][] items)137     private <T> AppearAnimationProperties getDelays(T[][] items) {
138         long maxDelay = -1;
139         mProperties.maxDelayColIndex = -1;
140         mProperties.maxDelayRowIndex = -1;
141         mProperties.delays = new long[items.length][];
142         for (int row = 0; row < items.length; row++) {
143             T[] columns = items[row];
144             mProperties.delays[row] = new long[columns.length];
145             for (int col = 0; col < columns.length; col++) {
146                 long delay = calculateDelay(row, col);
147                 mProperties.delays[row][col] = delay;
148                 if (items[row][col] != null && delay > maxDelay) {
149                     maxDelay = delay;
150                     mProperties.maxDelayColIndex = col;
151                     mProperties.maxDelayRowIndex = row;
152                 }
153             }
154         }
155         return mProperties;
156     }
157 
calculateDelay(int row, int col)158     protected long calculateDelay(int row, int col) {
159         return (long) ((row * 40 + col * (Math.pow(row, 0.4) + 0.4) * 20) * mDelayScale);
160     }
161 
getInterpolator()162     public Interpolator getInterpolator() {
163         return mInterpolator;
164     }
165 
getStartTranslation()166     public float getStartTranslation() {
167         return mStartTranslation;
168     }
169 
170     @Override
createAnimation(View view, long delay, long duration, float translationY, boolean appearing, Interpolator interpolator, Runnable endRunnable)171     public void createAnimation(View view, long delay, long duration, float translationY,
172             boolean appearing, Interpolator interpolator, Runnable endRunnable) {
173         if (view != null) {
174             view.setAlpha(appearing ? 0f : 1.0f);
175             view.setTranslationY(appearing ? translationY : 0);
176             view.animate()
177                     .alpha(appearing ? 1f : 0f)
178                     .translationY(appearing ? 0 : translationY)
179                     .setInterpolator(interpolator)
180                     .setDuration(duration)
181                     .setStartDelay(delay);
182             if (view.hasOverlappingRendering()) {
183                 view.animate().withLayer();
184             }
185             if (endRunnable != null) {
186                 view.animate().withEndAction(endRunnable);
187             }
188         }
189     }
190 
191     public class AppearAnimationProperties {
192         public long[][] delays;
193         public int maxDelayRowIndex;
194         public int maxDelayColIndex;
195     }
196 }
197