blob: 164215befe796bfb2886782b7e0ec70cd8f53d3e [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;
Lucas Dupine1bb9982019-01-24 16:42:52 -080022import com.android.systemui.R;
Rohan Shah20790b82018-07-02 17:21:04 -070023import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
Selim Cinek4ffd6362015-12-29 15:12:23 +010024
25/**
26 * A helper to fade views in and out.
27 */
28public class CrossFadeHelper {
29 public static final long ANIMATION_DURATION_LENGTH = 210;
30
Selim Cinek999230c2019-06-19 15:36:44 -070031 public static void fadeOut(final View view) {
32 fadeOut(view, null);
33 }
34
Selim Cinek4ffd6362015-12-29 15:12:23 +010035 public static void fadeOut(final View view, final Runnable endRunnable) {
Selim Cinekd03518c2018-03-15 12:13:51 -070036 fadeOut(view, ANIMATION_DURATION_LENGTH, 0, endRunnable);
37 }
38
39 public static void fadeOut(final View view, long duration, int delay,
40 final Runnable endRunnable) {
Selim Cinek4ffd6362015-12-29 15:12:23 +010041 view.animate().cancel();
42 view.animate()
43 .alpha(0f)
Selim Cinekd03518c2018-03-15 12:13:51 -070044 .setDuration(duration)
Selim Cinekc18010f2016-01-20 13:41:30 -080045 .setInterpolator(Interpolators.ALPHA_OUT)
Selim Cinekd03518c2018-03-15 12:13:51 -070046 .setStartDelay(delay)
Selim Cinek4ffd6362015-12-29 15:12:23 +010047 .withEndAction(new Runnable() {
48 @Override
49 public void run() {
50 if (endRunnable != null) {
51 endRunnable.run();
52 }
53 view.setVisibility(View.INVISIBLE);
54 }
55 });
56 if (view.hasOverlappingRendering()) {
57 view.animate().withLayer();
58 }
Selim Cinek8f2f6a62016-02-23 19:56:31 -080059 }
Selim Cinek4ffd6362015-12-29 15:12:23 +010060
Selim Cinek8f2f6a62016-02-23 19:56:31 -080061 public static void fadeOut(View view, float fadeOutAmount) {
Selim Cinek8a71ad02016-09-07 20:00:25 -070062 fadeOut(view, fadeOutAmount, true /* remap */);
63 }
64
65 /**
66 * Fade out a view by a given progress amount
67 * @param view the view to fade out
68 * @param fadeOutAmount how much the view is faded out. 0 means not at all and 1 means fully
69 * faded out
70 * @param remap whether the fade amount should be remapped to the shorter duration
71 * {@link #ANIMATION_DURATION_LENGTH} from the normal fade duration
72 * {@link StackStateAnimator#ANIMATION_DURATION_STANDARD} in order to have a faster fading.
73 *
74 * @see #fadeIn(View, float, boolean)
75 */
76 public static void fadeOut(View view, float fadeOutAmount, boolean remap) {
Selim Cinek8f2f6a62016-02-23 19:56:31 -080077 view.animate().cancel();
78 if (fadeOutAmount == 1.0f) {
79 view.setVisibility(View.INVISIBLE);
80 } else if (view.getVisibility() == View.INVISIBLE) {
81 view.setVisibility(View.VISIBLE);
82 }
Selim Cinek8a71ad02016-09-07 20:00:25 -070083 if (remap) {
84 fadeOutAmount = mapToFadeDuration(fadeOutAmount);
85 }
Selim Cinek8f2f6a62016-02-23 19:56:31 -080086 float alpha = Interpolators.ALPHA_OUT.getInterpolation(1.0f - fadeOutAmount);
87 view.setAlpha(alpha);
88 updateLayerType(view, alpha);
89 }
90
91 private static float mapToFadeDuration(float fadeOutAmount) {
92 // Assuming a linear interpolator, we can easily map it to our new duration
93 float endPoint = (float) ANIMATION_DURATION_LENGTH
94 / (float) StackStateAnimator.ANIMATION_DURATION_STANDARD;
95 return Math.min(fadeOutAmount / endPoint, 1.0f);
96 }
97
98 private static void updateLayerType(View view, float alpha) {
99 if (view.hasOverlappingRendering() && alpha > 0.0f && alpha < 1.0f) {
Lucas Dupine1bb9982019-01-24 16:42:52 -0800100 if (view.getLayerType() != View.LAYER_TYPE_HARDWARE) {
101 view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
102 view.setTag(R.id.cross_fade_layer_type_changed_tag, true);
103 }
104 } else if (view.getLayerType() == View.LAYER_TYPE_HARDWARE
105 && view.getTag(R.id.cross_fade_layer_type_changed_tag) != null) {
106 if (view.getTag(R.id.cross_fade_layer_type_changed_tag) != null) {
107 view.setLayerType(View.LAYER_TYPE_NONE, null);
108 }
Selim Cinek8f2f6a62016-02-23 19:56:31 -0800109 }
Selim Cinek4ffd6362015-12-29 15:12:23 +0100110 }
111
112 public static void fadeIn(final View view) {
Selim Cinekd03518c2018-03-15 12:13:51 -0700113 fadeIn(view, ANIMATION_DURATION_LENGTH, 0);
114 }
115
116 public static void fadeIn(final View view, long duration, int delay) {
Selim Cinek4ffd6362015-12-29 15:12:23 +0100117 view.animate().cancel();
118 if (view.getVisibility() == View.INVISIBLE) {
119 view.setAlpha(0.0f);
120 view.setVisibility(View.VISIBLE);
121 }
122 view.animate()
123 .alpha(1f)
Selim Cinekd03518c2018-03-15 12:13:51 -0700124 .setDuration(duration)
125 .setStartDelay(delay)
Selim Cinekc18010f2016-01-20 13:41:30 -0800126 .setInterpolator(Interpolators.ALPHA_IN)
Selim Cinekfd3e2622016-01-12 16:02:42 -0800127 .withEndAction(null);
Lucas Dupine1bb9982019-01-24 16:42:52 -0800128 if (view.hasOverlappingRendering() && view.getLayerType() != View.LAYER_TYPE_HARDWARE) {
Selim Cinek4ffd6362015-12-29 15:12:23 +0100129 view.animate().withLayer();
130 }
131 }
Selim Cinek8f2f6a62016-02-23 19:56:31 -0800132
133 public static void fadeIn(View view, float fadeInAmount) {
Selim Cinek8a71ad02016-09-07 20:00:25 -0700134 fadeIn(view, fadeInAmount, true /* remap */);
135 }
136
137 /**
138 * Fade in a view by a given progress amount
139 * @param view the view to fade in
140 * @param fadeInAmount how much the view is faded in. 0 means not at all and 1 means fully
141 * faded in.
142 * @param remap whether the fade amount should be remapped to the shorter duration
143 * {@link #ANIMATION_DURATION_LENGTH} from the normal fade duration
144 * {@link StackStateAnimator#ANIMATION_DURATION_STANDARD} in order to have a faster fading.
145 *
146 * @see #fadeOut(View, float, boolean)
147 */
148 public static void fadeIn(View view, float fadeInAmount, boolean remap) {
Selim Cinek8f2f6a62016-02-23 19:56:31 -0800149 view.animate().cancel();
150 if (view.getVisibility() == View.INVISIBLE) {
151 view.setVisibility(View.VISIBLE);
152 }
Selim Cinek8a71ad02016-09-07 20:00:25 -0700153 if (remap) {
154 fadeInAmount = mapToFadeDuration(fadeInAmount);
155 }
Selim Cinek8f2f6a62016-02-23 19:56:31 -0800156 float alpha = Interpolators.ALPHA_IN.getInterpolation(fadeInAmount);
157 view.setAlpha(alpha);
158 updateLayerType(view, alpha);
159 }
Selim Cinek4ffd6362015-12-29 15:12:23 +0100160}