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;
43 private LatestItemView mLatestItemView;
46 * Is this notification expanded by the system. The expansion state can be overridden by the
49 private boolean mIsSystemExpanded;
50 private SizeAdaptiveLayout mPublicLayout;
51 private SizeAdaptiveLayout mPrivateLayout;
52 private int mMaxExpandHeight;
53 private boolean mMaxHeightNeedsUpdate;
55 public ExpandableNotificationRow(Context context, AttributeSet attrs) {
56 super(context, attrs);
60 protected void onFinishInflate() {
61 super.onFinishInflate();
62 mPublicLayout = (SizeAdaptiveLayout) findViewById(R.id.expandedPublic);
63 mPrivateLayout = (SizeAdaptiveLayout) findViewById(R.id.expanded);
64 mLatestItemView = (LatestItemView) findViewById(R.id.container);
68 public void setHeightRange(int rowMinHeight, int rowMaxHeight) {
69 mRowMinHeight = rowMinHeight;
70 mRowMaxHeight = rowMaxHeight;
71 mMaxHeightNeedsUpdate = true;
74 public boolean isExpandable() {
78 public void setExpandable(boolean expandable) {
79 mExpandable = expandable;
83 * @return whether the user has changed the expansion state
85 public boolean hasUserChangedExpansion() {
86 return mHasUserChangedExpansion;
89 public boolean isUserExpanded() {
94 * Set this notification to be expanded by the user
96 * @param userExpanded whether the user wants this notification to be expanded
98 public void setUserExpanded(boolean userExpanded) {
99 mHasUserChangedExpansion = true;
100 mUserExpanded = userExpanded;
103 public boolean isUserLocked() {
107 public void setUserLocked(boolean userLocked) {
108 mUserLocked = userLocked;
112 * @return has the system set this notification to be expanded
114 public boolean isSystemExpanded() {
115 return mIsSystemExpanded;
119 * Set this notification to be expanded by the system.
121 * @param expand whether the system wants this notification to be expanded.
123 public void setSystemExpanded(boolean expand) {
124 mIsSystemExpanded = expand;
125 applyExpansionToLayout(expand);
129 * Apply an expansion state to the layout.
131 * @param expand should the layout be in the expanded state
133 public void applyExpansionToLayout(boolean expand) {
134 ViewGroup.LayoutParams lp = getLayoutParams();
135 if (expand && mExpandable) {
136 lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
138 lp.height = mRowMinHeight;
144 * If {@link #isExpanded()} then this is the greatest possible height this view can
145 * get and otherwise it is {@link #mRowMinHeight}.
147 * @return the maximum allowed expansion height of this view.
149 public int getMaximumAllowedExpandHeight() {
150 boolean inExpansionState = isExpanded();
151 if (!inExpansionState) {
152 // not expanded, so we return the collapsed size
153 return mRowMinHeight;
156 return mShowingPublic ? mRowMinHeight : getMaxExpandHeight();
159 private void updateMaxExpandHeight() {
160 ViewGroup.LayoutParams lp = getLayoutParams();
161 int oldHeight = lp.height;
162 lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
164 measure(View.MeasureSpec.makeMeasureSpec(getMeasuredWidth(), View.MeasureSpec.EXACTLY),
165 View.MeasureSpec.makeMeasureSpec(mRowMaxHeight, View.MeasureSpec.AT_MOST));
166 lp.height = oldHeight;
168 mMaxExpandHeight = getMeasuredHeight();
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.
177 * @return whether the view state is currently expanded.
179 private boolean isExpanded() {
180 return !hasUserChangedExpansion() && isSystemExpanded() || isUserExpanded();
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;
189 public void setShowingPublic(boolean show) {
190 mShowingPublic = show;
192 // bail out if no public version
193 if (mPublicLayout.getChildCount() == 0) return;
196 mPublicLayout.setVisibility(show ? View.VISIBLE : View.GONE);
197 mPrivateLayout.setVisibility(show ? View.GONE : View.VISIBLE);
201 * Sets the notification as dimmed, meaning that it will appear in a more gray variant.
203 public void setDimmed(boolean dimmed) {
204 mLatestItemView.setDimmed(dimmed);
207 public int getMaxExpandHeight() {
208 if (mMaxHeightNeedsUpdate) {
209 updateMaxExpandHeight();
210 mMaxHeightNeedsUpdate = false;
212 return mMaxExpandHeight;
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.
219 public void setLocked(boolean locked) {
220 mLatestItemView.setLocked(locked);
224 * Sets the resource id for the background of this notification.
226 * @param bgResId The background resource to use in normal state.
227 * @param dimmedBgResId The background resource to use in dimmed state.
229 public void setBackgroundResourceIds(int bgResId, int dimmedBgResId) {
230 mLatestItemView.setBackgroundResourceIds(bgResId, dimmedBgResId);