2 * Copyright (C) 2013 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.systemui.statusbar;
19 import android.content.Context;
20 import android.util.AttributeSet;
21 import android.view.View;
22 import android.view.ViewGroup;
23 import android.widget.FrameLayout;
25 import com.android.internal.widget.SizeAdaptiveLayout;
26 import com.android.systemui.R;
28 public class ExpandableNotificationRow extends FrameLayout {
29 private int mRowMinHeight;
30 private int mRowMaxHeight;
32 /** Does this row contain layouts that can adapt to row expansion */
33 private boolean mExpandable;
34 /** 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 */
37 private boolean mUserExpanded;
38 /** Is the user touching this row */
39 private boolean mUserLocked;
40 /** Are we showing the "public" version */
41 private boolean mShowingPublic;
44 * Is this notification expanded by the system. The expansion state can be overridden by the
47 private boolean mIsSystemExpanded;
48 private SizeAdaptiveLayout mPublicLayout;
49 private SizeAdaptiveLayout mPrivateLayout;
50 private int mMaxExpandHeight;
51 private boolean mMaxHeightNeedsUpdate;
53 public ExpandableNotificationRow(Context context, AttributeSet attrs) {
54 super(context, attrs);
58 protected void onFinishInflate() {
59 super.onFinishInflate();
60 mPublicLayout = (SizeAdaptiveLayout) findViewById(R.id.expandedPublic);
61 mPrivateLayout = (SizeAdaptiveLayout) findViewById(R.id.expanded);
64 public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
65 mRowMinHeight = rowMinHeight;
66 mRowMaxHeight = rowMaxHeight;
67 mMaxHeightNeedsUpdate = true;
70 public boolean isExpandable() {
74 public void setExpandable(boolean expandable) {
75 mExpandable = expandable;
79 * @return whether the user has changed the expansion state
81 public boolean hasUserChangedExpansion() {
82 return mHasUserChangedExpansion;
85 public boolean isUserExpanded() {
90 * Set this notification to be expanded by the user
92 * @param userExpanded whether the user wants this notification to be expanded
94 public void setUserExpanded(boolean userExpanded) {
95 mHasUserChangedExpansion = true;
96 mUserExpanded = userExpanded;
99 public boolean isUserLocked() {
103 public void setUserLocked(boolean userLocked) {
104 mUserLocked = userLocked;
108 * @return has the system set this notification to be expanded
110 public boolean isSystemExpanded() {
111 return mIsSystemExpanded;
115 * Set this notification to be expanded by the system.
117 * @param expand whether the system wants this notification to be expanded.
119 public void setSystemExpanded(boolean expand) {
120 mIsSystemExpanded = expand;
121 applyExpansionToLayout(expand);
125 * Apply an expansion state to the layout.
127 * @param expand should the layout be in the expanded state
129 public void applyExpansionToLayout(boolean expand) {
130 ViewGroup.LayoutParams lp = getLayoutParams();
131 if (expand && mExpandable) {
132 lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
134 lp.height = mRowMinHeight;
140 * If {@link #isExpanded()} then this is the greatest possible height this view can
141 * get and otherwise it is {@link #mRowMinHeight}.
143 * @return the maximum allowed expansion height of this view.
145 public int getMaximumAllowedExpandHeight() {
146 boolean inExpansionState = isExpanded();
147 if (!inExpansionState) {
148 // not expanded, so we return the collapsed size
149 return mRowMinHeight;
152 return mShowingPublic ? mRowMinHeight : getMaxExpandHeight();
157 private void updateMaxExpandHeight() {
158 ViewGroup.LayoutParams lp = getLayoutParams();
159 int oldHeight = lp.height;
160 lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
162 measure(View.MeasureSpec.makeMeasureSpec(getMeasuredWidth(), View.MeasureSpec.EXACTLY),
163 View.MeasureSpec.makeMeasureSpec(mRowMaxHeight, View.MeasureSpec.AT_MOST));
164 lp.height = oldHeight;
166 mMaxExpandHeight = getMeasuredHeight();
170 * Check whether the view state is currently expanded. This is given by the system in {@link
171 * #setSystemExpanded(boolean)} and can be overridden by user expansion or
172 * collapsing in {@link #setUserExpanded(boolean)}. Note that the visual appearance of this
173 * view can differ from this state, if layout params are modified from outside.
175 * @return whether the view state is currently expanded.
177 private boolean isExpanded() {
178 return !hasUserChangedExpansion() && isSystemExpanded() || isUserExpanded();
182 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
183 super.onLayout(changed, left, top, right, bottom);
184 mMaxHeightNeedsUpdate = true;
187 public void setShowingPublic(boolean show) {
188 mShowingPublic = show;
190 // bail out if no public version
191 if (mPublicLayout.getChildCount() == 0) return;
194 mPublicLayout.setVisibility(show ? View.VISIBLE : View.GONE);
195 mPrivateLayout.setVisibility(show ? View.GONE : View.VISIBLE);
198 public int getMaxExpandHeight() {
199 if (mMaxHeightNeedsUpdate) {
200 updateMaxExpandHeight();
201 mMaxHeightNeedsUpdate = false;
203 return mMaxExpandHeight;