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.systemui.statusbar;
18 
19 import android.content.Context;
20 import android.util.AttributeSet;
21 import android.view.View;
22 import android.view.animation.Interpolator;
23 
24 import com.android.systemui.statusbar.phone.PhoneStatusBar;
25 
26 /**
27  * A common base class for all views in the notification stack scroller which don't have a
28  * background.
29  */
30 public abstract class StackScrollerDecorView extends ExpandableView {
31 
32     protected View mContent;
33     private boolean mIsVisible;
34     private boolean mAnimating;
35     private boolean mWillBeGone;
36 
StackScrollerDecorView(Context context, AttributeSet attrs)37     public StackScrollerDecorView(Context context, AttributeSet attrs) {
38         super(context, attrs);
39     }
40 
41     @Override
onFinishInflate()42     protected void onFinishInflate() {
43         super.onFinishInflate();
44         mContent = findContentView();
45         setInvisible();
46     }
47 
48     @Override
onLayout(boolean changed, int left, int top, int right, int bottom)49     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
50         super.onLayout(changed, left, top, right, bottom);
51         setOutlineProvider(null);
52     }
53 
54     @Override
isTransparent()55     public boolean isTransparent() {
56         return true;
57     }
58 
performVisibilityAnimation(boolean nowVisible)59     public void performVisibilityAnimation(boolean nowVisible) {
60         animateText(nowVisible, null /* onFinishedRunnable */);
61     }
62 
performVisibilityAnimation(boolean nowVisible, Runnable onFinishedRunnable)63     public void performVisibilityAnimation(boolean nowVisible, Runnable onFinishedRunnable) {
64         animateText(nowVisible, onFinishedRunnable);
65     }
66 
isVisible()67     public boolean isVisible() {
68         return mIsVisible || mAnimating;
69     }
70 
71     /**
72      * Animate the text to a new visibility.
73      *
74      * @param nowVisible should it now be visible
75      * @param onFinishedRunnable A runnable which should be run when the animation is
76      *        finished.
77      */
animateText(boolean nowVisible, final Runnable onFinishedRunnable)78     private void animateText(boolean nowVisible, final Runnable onFinishedRunnable) {
79         if (nowVisible != mIsVisible) {
80             // Animate text
81             float endValue = nowVisible ? 1.0f : 0.0f;
82             Interpolator interpolator;
83             if (nowVisible) {
84                 interpolator = PhoneStatusBar.ALPHA_IN;
85             } else {
86                 interpolator = PhoneStatusBar.ALPHA_OUT;
87             }
88             mAnimating = true;
89             mContent.animate()
90                     .alpha(endValue)
91                     .setInterpolator(interpolator)
92                     .setDuration(260)
93                     .withEndAction(new Runnable() {
94                         @Override
95                         public void run() {
96                             mAnimating = false;
97                             if (onFinishedRunnable != null) {
98                                 onFinishedRunnable.run();
99                             }
100                         }
101                     });
102             mIsVisible = nowVisible;
103         } else {
104             if (onFinishedRunnable != null) {
105                 onFinishedRunnable.run();
106             }
107         }
108     }
109 
setInvisible()110     public void setInvisible() {
111         mContent.setAlpha(0.0f);
112         mIsVisible = false;
113     }
114 
115     @Override
performRemoveAnimation(long duration, float translationDirection, Runnable onFinishedRunnable)116     public void performRemoveAnimation(long duration, float translationDirection,
117             Runnable onFinishedRunnable) {
118         // TODO: Use duration
119         performVisibilityAnimation(false);
120     }
121 
122     @Override
performAddAnimation(long delay, long duration)123     public void performAddAnimation(long delay, long duration) {
124         // TODO: use delay and duration
125         performVisibilityAnimation(true);
126     }
127 
128     @Override
hasOverlappingRendering()129     public boolean hasOverlappingRendering() {
130         return false;
131     }
132 
cancelAnimation()133     public void cancelAnimation() {
134         mContent.animate().cancel();
135     }
136 
willBeGone()137     public boolean willBeGone() {
138         return mWillBeGone;
139     }
140 
setWillBeGone(boolean willBeGone)141     public void setWillBeGone(boolean willBeGone) {
142         mWillBeGone = willBeGone;
143     }
144 
findContentView()145     protected abstract View findContentView();
146 }
147