blob: e8f0925dcc7119605e5ea715f7ab6f4ec05f91e3 [file] [log] [blame]
Selim Cinek4ffd6362015-12-29 15:12:23 +01001/*
2 * Copyright (C) 2016 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
17package com.android.systemui.statusbar;
18
19import android.view.View;
20
Winsonc0d70582016-01-29 10:24:39 -080021import com.android.systemui.Interpolators;
Selim Cinek8f2f6a62016-02-23 19:56:31 -080022import com.android.systemui.statusbar.stack.StackStateAnimator;
Selim Cinek4ffd6362015-12-29 15:12:23 +010023
24/**
25 * A helper to fade views in and out.
26 */
27public class CrossFadeHelper {
28 public static final long ANIMATION_DURATION_LENGTH = 210;
29
30 public static void fadeOut(final View view, final Runnable endRunnable) {
31 view.animate().cancel();
32 view.animate()
33 .alpha(0f)
34 .setDuration(ANIMATION_DURATION_LENGTH)
Selim Cinekc18010f2016-01-20 13:41:30 -080035 .setInterpolator(Interpolators.ALPHA_OUT)
Selim Cinek4ffd6362015-12-29 15:12:23 +010036 .withEndAction(new Runnable() {
37 @Override
38 public void run() {
39 if (endRunnable != null) {
40 endRunnable.run();
41 }
42 view.setVisibility(View.INVISIBLE);
43 }
44 });
45 if (view.hasOverlappingRendering()) {
46 view.animate().withLayer();
47 }
Selim Cinek8f2f6a62016-02-23 19:56:31 -080048 }
Selim Cinek4ffd6362015-12-29 15:12:23 +010049
Selim Cinek8f2f6a62016-02-23 19:56:31 -080050 public static void fadeOut(View view, float fadeOutAmount) {
Selim Cinek8a71ad02016-09-07 20:00:25 -070051 fadeOut(view, fadeOutAmount, true /* remap */);
52 }
53
54 /**
55 * Fade out a view by a given progress amount
56 * @param view the view to fade out
57 * @param fadeOutAmount how much the view is faded out. 0 means not at all and 1 means fully
58 * faded out
59 * @param remap whether the fade amount should be remapped to the shorter duration
60 * {@link #ANIMATION_DURATION_LENGTH} from the normal fade duration
61 * {@link StackStateAnimator#ANIMATION_DURATION_STANDARD} in order to have a faster fading.
62 *
63 * @see #fadeIn(View, float, boolean)
64 */
65 public static void fadeOut(View view, float fadeOutAmount, boolean remap) {
Selim Cinek8f2f6a62016-02-23 19:56:31 -080066 view.animate().cancel();
67 if (fadeOutAmount == 1.0f) {
68 view.setVisibility(View.INVISIBLE);
69 } else if (view.getVisibility() == View.INVISIBLE) {
70 view.setVisibility(View.VISIBLE);
71 }
Selim Cinek8a71ad02016-09-07 20:00:25 -070072 if (remap) {
73 fadeOutAmount = mapToFadeDuration(fadeOutAmount);
74 }
Selim Cinek8f2f6a62016-02-23 19:56:31 -080075 float alpha = Interpolators.ALPHA_OUT.getInterpolation(1.0f - fadeOutAmount);
76 view.setAlpha(alpha);
77 updateLayerType(view, alpha);
78 }
79
80 private static float mapToFadeDuration(float fadeOutAmount) {
81 // Assuming a linear interpolator, we can easily map it to our new duration
82 float endPoint = (float) ANIMATION_DURATION_LENGTH
83 / (float) StackStateAnimator.ANIMATION_DURATION_STANDARD;
84 return Math.min(fadeOutAmount / endPoint, 1.0f);
85 }
86
87 private static void updateLayerType(View view, float alpha) {
88 if (view.hasOverlappingRendering() && alpha > 0.0f && alpha < 1.0f) {
89 view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
90 } else if (view.getLayerType() == View.LAYER_TYPE_HARDWARE) {
91 view.setLayerType(View.LAYER_TYPE_NONE, null);
92 }
Selim Cinek4ffd6362015-12-29 15:12:23 +010093 }
94
95 public static void fadeIn(final View view) {
96 view.animate().cancel();
97 if (view.getVisibility() == View.INVISIBLE) {
98 view.setAlpha(0.0f);
99 view.setVisibility(View.VISIBLE);
100 }
101 view.animate()
102 .alpha(1f)
103 .setDuration(ANIMATION_DURATION_LENGTH)
Selim Cinekc18010f2016-01-20 13:41:30 -0800104 .setInterpolator(Interpolators.ALPHA_IN)
Selim Cinekfd3e2622016-01-12 16:02:42 -0800105 .withEndAction(null);
Selim Cinek4ffd6362015-12-29 15:12:23 +0100106 if (view.hasOverlappingRendering()) {
107 view.animate().withLayer();
108 }
109 }
Selim Cinek8f2f6a62016-02-23 19:56:31 -0800110
111 public static void fadeIn(View view, float fadeInAmount) {
Selim Cinek8a71ad02016-09-07 20:00:25 -0700112 fadeIn(view, fadeInAmount, true /* remap */);
113 }
114
115 /**
116 * Fade in a view by a given progress amount
117 * @param view the view to fade in
118 * @param fadeInAmount how much the view is faded in. 0 means not at all and 1 means fully
119 * faded in.
120 * @param remap whether the fade amount should be remapped to the shorter duration
121 * {@link #ANIMATION_DURATION_LENGTH} from the normal fade duration
122 * {@link StackStateAnimator#ANIMATION_DURATION_STANDARD} in order to have a faster fading.
123 *
124 * @see #fadeOut(View, float, boolean)
125 */
126 public static void fadeIn(View view, float fadeInAmount, boolean remap) {
Selim Cinek8f2f6a62016-02-23 19:56:31 -0800127 view.animate().cancel();
128 if (view.getVisibility() == View.INVISIBLE) {
129 view.setVisibility(View.VISIBLE);
130 }
Selim Cinek8a71ad02016-09-07 20:00:25 -0700131 if (remap) {
132 fadeInAmount = mapToFadeDuration(fadeInAmount);
133 }
Selim Cinek8f2f6a62016-02-23 19:56:31 -0800134 float alpha = Interpolators.ALPHA_IN.getInterpolation(fadeInAmount);
135 view.setAlpha(alpha);
136 updateLayerType(view, alpha);
137 }
Selim Cinek4ffd6362015-12-29 15:12:23 +0100138}