StatusBarHeaderView.java revision 1ab15ca80bb70d4ffc48bce0bc36c3a1d58090d1
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 17package com.android.systemui.statusbar.phone; 18 19import android.content.Context; 20import android.content.Intent; 21import android.graphics.Outline; 22import android.graphics.Rect; 23import android.util.AttributeSet; 24import android.view.View; 25import android.view.ViewGroup; 26import android.widget.ImageView; 27import android.widget.LinearLayout; 28import android.widget.RelativeLayout; 29import android.widget.TextView; 30 31import com.android.systemui.R; 32import com.android.systemui.qs.QSPanel; 33import com.android.systemui.settings.BrightnessController; 34import com.android.systemui.settings.ToggleSlider; 35import com.android.systemui.statusbar.policy.UserInfoController; 36 37/** 38 * The view to manage the header area in the expanded status bar. 39 */ 40public class StatusBarHeaderView extends RelativeLayout implements View.OnClickListener { 41 42 /** 43 * How much the header expansion gets rubberbanded while expanding the panel. 44 */ 45 private static final float EXPANSION_RUBBERBAND_FACTOR = 0.35f; 46 47 private boolean mExpanded; 48 private boolean mOverscrolled; 49 private boolean mKeyguardShowing; 50 51 private View mBackground; 52 private ViewGroup mSystemIconsContainer; 53 private View mDateTime; 54 private View mKeyguardCarrierText; 55 private MultiUserSwitch mMultiUserSwitch; 56 private View mDate; 57 private View mStatusIcons; 58 private View mSignalCluster; 59 private View mSettingsButton; 60 private View mBrightnessContainer; 61 private View mEmergencyCallsOnly; 62 private TextView mChargingInfo; 63 64 private boolean mShowEmergencyCallsOnly; 65 private boolean mShowChargingInfo; 66 67 private int mCollapsedHeight; 68 private int mExpandedHeight; 69 private int mKeyguardHeight; 70 71 private int mKeyguardWidth = ViewGroup.LayoutParams.MATCH_PARENT; 72 private int mNormalWidth; 73 74 private ActivityStarter mActivityStarter; 75 private BrightnessController mBrightnessController; 76 private QSPanel mQSPanel; 77 78 private final Rect mClipBounds = new Rect(); 79 private final Outline mOutline = new Outline(); 80 81 public StatusBarHeaderView(Context context, AttributeSet attrs) { 82 super(context, attrs); 83 } 84 85 @Override 86 protected void onFinishInflate() { 87 super.onFinishInflate(); 88 mBackground = findViewById(R.id.background); 89 mSystemIconsContainer = (ViewGroup) findViewById(R.id.system_icons_container); 90 mDateTime = findViewById(R.id.datetime); 91 mKeyguardCarrierText = findViewById(R.id.keyguard_carrier_text); 92 mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch); 93 mDate = findViewById(R.id.date); 94 mSettingsButton = findViewById(R.id.settings_button); 95 mSettingsButton.setOnClickListener(this); 96 mBrightnessContainer = findViewById(R.id.brightness_container); 97 mBrightnessController = new BrightnessController(getContext(), 98 (ImageView) findViewById(R.id.brightness_icon), 99 (ToggleSlider) findViewById(R.id.brightness_slider)); 100 mEmergencyCallsOnly = findViewById(R.id.header_emergency_calls_only); 101 mChargingInfo = (TextView) findViewById(R.id.header_charging_info); 102 loadDimens(); 103 updateVisibilities(); 104 addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 105 @Override 106 public void onLayoutChange(View v, int left, int top, int right, 107 int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 108 if ((right - left) != (oldRight - oldLeft)) { 109 // width changed, update clipping 110 setClipping(getHeight()); 111 } 112 } 113 }); 114 } 115 116 private void loadDimens() { 117 mCollapsedHeight = getResources().getDimensionPixelSize(R.dimen.status_bar_header_height); 118 mExpandedHeight = getResources().getDimensionPixelSize( 119 R.dimen.status_bar_header_height_expanded); 120 mKeyguardHeight = getResources().getDimensionPixelSize( 121 R.dimen.status_bar_header_height_keyguard); 122 mNormalWidth = getLayoutParams().width; 123 } 124 125 public void setActivityStarter(ActivityStarter activityStarter) { 126 mActivityStarter = activityStarter; 127 } 128 129 public int getCollapsedHeight() { 130 return mKeyguardShowing ? mKeyguardHeight : mCollapsedHeight; 131 } 132 133 public int getExpandedHeight() { 134 return mExpandedHeight; 135 } 136 137 public void setExpanded(boolean expanded, boolean overscrolled) { 138 boolean changed = expanded != mExpanded; 139 boolean overscrollChanged = overscrolled != mOverscrolled; 140 mExpanded = expanded; 141 mOverscrolled = overscrolled; 142 if (changed || overscrollChanged) { 143 updateHeights(); 144 updateVisibilities(); 145 updateSystemIconsLayoutParams(); 146 updateBrightnessControllerState(); 147 updateZTranslation(); 148 updateClickTargets(); 149 updateWidth(); 150 if (mQSPanel != null) { 151 mQSPanel.setExpanded(expanded && !overscrolled); 152 } 153 } 154 } 155 156 private void updateHeights() { 157 boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded; 158 int height; 159 if (mExpanded) { 160 height = mExpandedHeight; 161 } else if (onKeyguardAndCollapsed) { 162 height = mKeyguardHeight; 163 } else { 164 height = mCollapsedHeight; 165 } 166 ViewGroup.LayoutParams lp = getLayoutParams(); 167 if (lp.height != height) { 168 lp.height = height; 169 setLayoutParams(lp); 170 } 171 int systemIconsContainerHeight = onKeyguardAndCollapsed ? mKeyguardHeight : mCollapsedHeight; 172 lp = mSystemIconsContainer.getLayoutParams(); 173 if (lp.height != systemIconsContainerHeight) { 174 lp.height = systemIconsContainerHeight; 175 mSystemIconsContainer.setLayoutParams(lp); 176 } 177 lp = mMultiUserSwitch.getLayoutParams(); 178 if (lp.height != systemIconsContainerHeight) { 179 lp.height = systemIconsContainerHeight; 180 mMultiUserSwitch.setLayoutParams(lp); 181 } 182 } 183 184 private void updateWidth() { 185 int width = (mKeyguardShowing && !mExpanded) ? mKeyguardWidth : mNormalWidth; 186 ViewGroup.LayoutParams lp = getLayoutParams(); 187 if (width != lp.width) { 188 lp.width = width; 189 setLayoutParams(lp); 190 } 191 } 192 193 private void updateVisibilities() { 194 boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded; 195 mBackground.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE); 196 mDateTime.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE); 197 mKeyguardCarrierText.setVisibility(onKeyguardAndCollapsed ? View.VISIBLE : View.GONE); 198 mDate.setVisibility(mExpanded ? View.VISIBLE : View.GONE); 199 mSettingsButton.setVisibility(mExpanded && !mOverscrolled ? View.VISIBLE : View.GONE); 200 mBrightnessContainer.setVisibility(mExpanded ? View.VISIBLE : View.GONE); 201 if (mStatusIcons != null) { 202 mStatusIcons.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE); 203 } 204 if (mSignalCluster != null) { 205 mSignalCluster.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE); 206 } 207 mEmergencyCallsOnly.setVisibility(mExpanded && !mOverscrolled && mShowEmergencyCallsOnly 208 ? VISIBLE : GONE); 209 mChargingInfo.setVisibility(mExpanded && !mOverscrolled && mShowChargingInfo 210 && !mShowEmergencyCallsOnly ? VISIBLE : GONE); 211 } 212 213 private void updateSystemIconsLayoutParams() { 214 RelativeLayout.LayoutParams lp = (LayoutParams) mSystemIconsContainer.getLayoutParams(); 215 boolean systemIconsAboveClock = mExpanded && !mOverscrolled 216 && mShowChargingInfo && !mShowEmergencyCallsOnly; 217 if (systemIconsAboveClock) { 218 lp.addRule(ALIGN_PARENT_START); 219 lp.removeRule(START_OF); 220 } else { 221 lp.addRule(RelativeLayout.START_OF, mExpanded 222 ? mSettingsButton.getId() 223 : mMultiUserSwitch.getId()); 224 lp.removeRule(ALIGN_PARENT_START); 225 } 226 227 RelativeLayout.LayoutParams clockLp = (LayoutParams) mDateTime.getLayoutParams(); 228 if (systemIconsAboveClock) { 229 clockLp.addRule(BELOW, mChargingInfo.getId()); 230 } else { 231 clockLp.addRule(BELOW, mEmergencyCallsOnly.getId()); 232 } 233 } 234 235 private void updateBrightnessControllerState() { 236 if (mExpanded) { 237 mBrightnessController.registerCallbacks(); 238 } else { 239 mBrightnessController.unregisterCallbacks(); 240 } 241 } 242 243 private void updateClickTargets() { 244 mDateTime.setClickable(mExpanded); 245 mMultiUserSwitch.setClickable(mExpanded); 246 } 247 248 private void updateZTranslation() { 249 250 // If we are on the Keyguard, we need to set our z position to zero, so we don't get 251 // shadows. 252 if (mKeyguardShowing && !mExpanded) { 253 setZ(0); 254 } else { 255 setTranslationZ(0); 256 } 257 } 258 259 public void setExpansion(float height) { 260 height = (height - mCollapsedHeight) * EXPANSION_RUBBERBAND_FACTOR + mCollapsedHeight; 261 if (height < mCollapsedHeight) { 262 height = mCollapsedHeight; 263 } 264 if (height > mExpandedHeight) { 265 height = mExpandedHeight; 266 } 267 setClipping(height); 268 } 269 270 private void setClipping(float height) { 271 mClipBounds.set(getPaddingLeft(), 0, getWidth() - getPaddingRight(), (int) height); 272 setClipBounds(mClipBounds); 273 mOutline.setRect(mClipBounds); 274 setOutline(mOutline); 275 } 276 277 public View getBackgroundView() { 278 return mBackground; 279 } 280 281 public void attachSystemIcons(LinearLayout systemIcons) { 282 mSystemIconsContainer.addView(systemIcons); 283 mStatusIcons = systemIcons.findViewById(R.id.statusIcons); 284 mSignalCluster = systemIcons.findViewById(R.id.signal_cluster); 285 } 286 287 public void onSystemIconsDetached() { 288 if (mStatusIcons != null) { 289 mStatusIcons.setVisibility(View.VISIBLE); 290 } 291 if (mSignalCluster != null) { 292 mSignalCluster.setVisibility(View.VISIBLE); 293 } 294 mStatusIcons = null; 295 mSignalCluster = null; 296 } 297 298 public void setKeyguardShowing(boolean keyguardShowing) { 299 mKeyguardShowing = keyguardShowing; 300 updateHeights(); 301 updateWidth(); 302 updateVisibilities(); 303 updateZTranslation(); 304 } 305 306 public void setUserInfoController(UserInfoController userInfoController) { 307 mMultiUserSwitch.setUserInfoController(userInfoController); 308 } 309 310 public void setOverlayParent(ViewGroup parent) { 311 mMultiUserSwitch.setOverlayParent(parent); 312 } 313 314 @Override 315 public void onClick(View v) { 316 if (v == mSettingsButton) { 317 startSettingsActivity(); 318 } 319 } 320 321 private void startSettingsActivity() { 322 mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS)); 323 } 324 325 public void setQSPanel(QSPanel qsp) { 326 mQSPanel = qsp; 327 if (mQSPanel != null) { 328 mQSPanel.setCallback(mQsPanelCallback); 329 } 330 } 331 332 private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() { 333 @Override 334 public void onShowingDetail(boolean showingDetail) { 335 mBrightnessContainer.animate().alpha(showingDetail ? 0 : 1).withLayer().start(); 336 } 337 }; 338 339 @Override 340 public boolean shouldDelayChildPressedState() { 341 return true; 342 } 343 344 public void setShowEmergencyCallsOnly(boolean show) { 345 mShowEmergencyCallsOnly = show; 346 if (mExpanded) { 347 updateVisibilities(); 348 updateSystemIconsLayoutParams(); 349 } 350 } 351 352 public void setShowChargingInfo(boolean showChargingInfo) { 353 mShowChargingInfo = showChargingInfo; 354 if (mExpanded) { 355 updateVisibilities(); 356 updateSystemIconsLayoutParams(); 357 } 358 } 359 360 public void setChargingInfo(CharSequence chargingInfo) { 361 mChargingInfo.setText(chargingInfo); 362 } 363} 364