blob: 7bacc13a4c152d5f40ddbc3a7b70b2293b4e65f9 [file] [log] [blame]
Chris Wren51c75102013-07-16 20:49:17 -04001/*
2 * Copyright (C) 2013 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.content.Context;
20import android.util.AttributeSet;
Dan Sandlera5e0f412014-01-23 15:11:54 -050021import android.view.View;
Chris Wren51c75102013-07-16 20:49:17 -040022import android.view.ViewGroup;
23import android.widget.FrameLayout;
24
Selim Cinek1685e632014-04-08 02:27:49 +020025import com.android.internal.widget.SizeAdaptiveLayout;
Dan Sandlera5e0f412014-01-23 15:11:54 -050026import com.android.systemui.R;
27
Chris Wren51c75102013-07-16 20:49:17 -040028public class ExpandableNotificationRow extends FrameLayout {
Selim Cinek1685e632014-04-08 02:27:49 +020029 private int mRowMinHeight;
30 private int mRowMaxHeight;
Chris Wren51c75102013-07-16 20:49:17 -040031
Selim Cinek1685e632014-04-08 02:27:49 +020032 /** Does this row contain layouts that can adapt to row expansion */
Chris Wren51c75102013-07-16 20:49:17 -040033 private boolean mExpandable;
Selim Cinek1685e632014-04-08 02:27:49 +020034 /** Has the user actively changed the expansion state of this row */
35 private boolean mHasUserChangedExpansion;
36 /** If {@link #mHasUserChangedExpansion}, has the user expanded this row */
Chris Wren51c75102013-07-16 20:49:17 -040037 private boolean mUserExpanded;
Selim Cinek1685e632014-04-08 02:27:49 +020038 /** Is the user touching this row */
Chris Wren51c75102013-07-16 20:49:17 -040039 private boolean mUserLocked;
Selim Cinek1685e632014-04-08 02:27:49 +020040 /** Are we showing the "public" version */
Dan Sandlera5e0f412014-01-23 15:11:54 -050041 private boolean mShowingPublic;
Chris Wren51c75102013-07-16 20:49:17 -040042
Jorim Jaggi251957d2014-04-09 04:24:09 +020043 private LatestItemView mLatestItemView;
44
Selim Cinek1685e632014-04-08 02:27:49 +020045 /**
46 * Is this notification expanded by the system. The expansion state can be overridden by the
47 * user expansion.
48 */
49 private boolean mIsSystemExpanded;
50 private SizeAdaptiveLayout mPublicLayout;
51 private SizeAdaptiveLayout mPrivateLayout;
52 private int mMaxExpandHeight;
53 private boolean mMaxHeightNeedsUpdate;
54
Chris Wren51c75102013-07-16 20:49:17 -040055 public ExpandableNotificationRow(Context context, AttributeSet attrs) {
56 super(context, attrs);
57 }
58
Jorim Jaggi251957d2014-04-09 04:24:09 +020059 @Override
60 protected void onFinishInflate() {
61 super.onFinishInflate();
Selim Cinek1685e632014-04-08 02:27:49 +020062 mPublicLayout = (SizeAdaptiveLayout) findViewById(R.id.expandedPublic);
63 mPrivateLayout = (SizeAdaptiveLayout) findViewById(R.id.expanded);
Jorim Jaggi251957d2014-04-09 04:24:09 +020064 mLatestItemView = (LatestItemView) findViewById(R.id.container);
65 }
66
Chris Wren51c75102013-07-16 20:49:17 -040067
Selim Cinek1685e632014-04-08 02:27:49 +020068 public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
69 mRowMinHeight = rowMinHeight;
70 mRowMaxHeight = rowMaxHeight;
71 mMaxHeightNeedsUpdate = true;
Chris Wren51c75102013-07-16 20:49:17 -040072 }
73
74 public boolean isExpandable() {
75 return mExpandable;
76 }
77
78 public void setExpandable(boolean expandable) {
79 mExpandable = expandable;
80 }
81
Selim Cinek1685e632014-04-08 02:27:49 +020082 /**
83 * @return whether the user has changed the expansion state
84 */
85 public boolean hasUserChangedExpansion() {
86 return mHasUserChangedExpansion;
87 }
88
Chris Wren51c75102013-07-16 20:49:17 -040089 public boolean isUserExpanded() {
90 return mUserExpanded;
91 }
92
Selim Cinek1685e632014-04-08 02:27:49 +020093 /**
94 * Set this notification to be expanded by the user
95 *
96 * @param userExpanded whether the user wants this notification to be expanded
97 */
Chris Wren51c75102013-07-16 20:49:17 -040098 public void setUserExpanded(boolean userExpanded) {
Selim Cinek1685e632014-04-08 02:27:49 +020099 mHasUserChangedExpansion = true;
Chris Wren51c75102013-07-16 20:49:17 -0400100 mUserExpanded = userExpanded;
101 }
102
103 public boolean isUserLocked() {
104 return mUserLocked;
105 }
106
107 public void setUserLocked(boolean userLocked) {
108 mUserLocked = userLocked;
109 }
110
Selim Cinek1685e632014-04-08 02:27:49 +0200111 /**
112 * @return has the system set this notification to be expanded
113 */
114 public boolean isSystemExpanded() {
115 return mIsSystemExpanded;
116 }
117
118 /**
119 * Set this notification to be expanded by the system.
120 *
121 * @param expand whether the system wants this notification to be expanded.
122 */
123 public void setSystemExpanded(boolean expand) {
124 mIsSystemExpanded = expand;
125 applyExpansionToLayout(expand);
126 }
127
128 /**
129 * Apply an expansion state to the layout.
130 *
131 * @param expand should the layout be in the expanded state
132 */
133 public void applyExpansionToLayout(boolean expand) {
Chris Wren51c75102013-07-16 20:49:17 -0400134 ViewGroup.LayoutParams lp = getLayoutParams();
135 if (expand && mExpandable) {
136 lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
137 } else {
Selim Cinek1685e632014-04-08 02:27:49 +0200138 lp.height = mRowMinHeight;
Chris Wren51c75102013-07-16 20:49:17 -0400139 }
140 setLayoutParams(lp);
141 }
Dan Sandlera5e0f412014-01-23 15:11:54 -0500142
Selim Cinek1685e632014-04-08 02:27:49 +0200143 /**
144 * If {@link #isExpanded()} then this is the greatest possible height this view can
145 * get and otherwise it is {@link #mRowMinHeight}.
146 *
147 * @return the maximum allowed expansion height of this view.
148 */
149 public int getMaximumAllowedExpandHeight() {
150 boolean inExpansionState = isExpanded();
151 if (!inExpansionState) {
152 // not expanded, so we return the collapsed size
153 return mRowMinHeight;
154 }
155
156 return mShowingPublic ? mRowMinHeight : getMaxExpandHeight();
157 }
158
Selim Cinek1685e632014-04-08 02:27:49 +0200159 private void updateMaxExpandHeight() {
160 ViewGroup.LayoutParams lp = getLayoutParams();
161 int oldHeight = lp.height;
162 lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
163 setLayoutParams(lp);
164 measure(View.MeasureSpec.makeMeasureSpec(getMeasuredWidth(), View.MeasureSpec.EXACTLY),
165 View.MeasureSpec.makeMeasureSpec(mRowMaxHeight, View.MeasureSpec.AT_MOST));
166 lp.height = oldHeight;
167 setLayoutParams(lp);
168 mMaxExpandHeight = getMeasuredHeight();
169 }
170
171 /**
172 * Check whether the view state is currently expanded. This is given by the system in {@link
173 * #setSystemExpanded(boolean)} and can be overridden by user expansion or
174 * collapsing in {@link #setUserExpanded(boolean)}. Note that the visual appearance of this
175 * view can differ from this state, if layout params are modified from outside.
176 *
177 * @return whether the view state is currently expanded.
178 */
179 private boolean isExpanded() {
180 return !hasUserChangedExpansion() && isSystemExpanded() || isUserExpanded();
181 }
182
183 @Override
184 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
185 super.onLayout(changed, left, top, right, bottom);
186 mMaxHeightNeedsUpdate = true;
187 }
188
Dan Sandlera5e0f412014-01-23 15:11:54 -0500189 public void setShowingPublic(boolean show) {
190 mShowingPublic = show;
Dan Sandlera5e0f412014-01-23 15:11:54 -0500191
192 // bail out if no public version
Selim Cinek1685e632014-04-08 02:27:49 +0200193 if (mPublicLayout.getChildCount() == 0) return;
Dan Sandlera5e0f412014-01-23 15:11:54 -0500194
195 // TODO: animation?
Selim Cinek1685e632014-04-08 02:27:49 +0200196 mPublicLayout.setVisibility(show ? View.VISIBLE : View.GONE);
197 mPrivateLayout.setVisibility(show ? View.GONE : View.VISIBLE);
Dan Sandlera5e0f412014-01-23 15:11:54 -0500198 }
Jorim Jaggi251957d2014-04-09 04:24:09 +0200199
200 /**
201 * Sets the notification as dimmed, meaning that it will appear in a more gray variant.
202 */
203 public void setDimmed(boolean dimmed) {
204 mLatestItemView.setDimmed(dimmed);
205 }
206
Selim Cinek1685e632014-04-08 02:27:49 +0200207 public int getMaxExpandHeight() {
208 if (mMaxHeightNeedsUpdate) {
209 updateMaxExpandHeight();
210 mMaxHeightNeedsUpdate = false;
211 }
212 return mMaxExpandHeight;
Chris Wren51c75102013-07-16 20:49:17 -0400213 }
Jorim Jaggi584a7aa2014-04-10 23:26:13 +0200214
Jorim Jaggi251957d2014-04-09 04:24:09 +0200215 /**
216 * Sets the notification as locked. In the locked state, the first tap will produce a quantum
217 * ripple to make the notification brighter and only the second tap will cause a click.
218 */
219 public void setLocked(boolean locked) {
220 mLatestItemView.setLocked(locked);
221 }
Chris Wren51c75102013-07-16 20:49:17 -0400222}