StatusBarHeaderView.java revision 312b792421f243eb1db08534a554a4630ba2ea55
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.graphics.drawable.Drawable; 24import android.util.AttributeSet; 25import android.view.View; 26import android.view.ViewGroup; 27import android.view.ViewOutlineProvider; 28import android.widget.ImageView; 29import android.widget.LinearLayout; 30import android.widget.RelativeLayout; 31import android.widget.Switch; 32import android.widget.TextView; 33 34import com.android.systemui.R; 35import com.android.systemui.qs.QSPanel; 36import com.android.systemui.qs.QSTile; 37import com.android.systemui.statusbar.policy.BatteryController; 38import com.android.systemui.statusbar.policy.UserInfoController; 39 40/** 41 * The view to manage the header area in the expanded status bar. 42 */ 43public class StatusBarHeaderView extends RelativeLayout implements View.OnClickListener, 44 BatteryController.BatteryStateChangeCallback { 45 46 private boolean mExpanded; 47 private boolean mListening; 48 private boolean mOverscrolled; 49 private boolean mKeyguardShowing; 50 private boolean mCharging; 51 52 private ViewGroup mSystemIconsContainer; 53 private View mSystemIconsSuperContainer; 54 private View mDateTime; 55 private View mTime; 56 private View mAmPm; 57 private View mKeyguardCarrierText; 58 private MultiUserSwitch mMultiUserSwitch; 59 private ImageView mMultiUserAvatar; 60 private View mDateCollapsed; 61 private View mDateExpanded; 62 private View mStatusIcons; 63 private View mSignalCluster; 64 private View mSettingsButton; 65 private View mQsDetailHeader; 66 private TextView mQsDetailHeaderTitle; 67 private Switch mQsDetailHeaderSwitch; 68 private View mEmergencyCallsOnly; 69 private TextView mBatteryLevel; 70 71 private boolean mShowEmergencyCallsOnly; 72 private boolean mKeyguardUserSwitcherShowing; 73 74 private int mCollapsedHeight; 75 private int mExpandedHeight; 76 private int mKeyguardHeight; 77 78 private int mKeyguardWidth = ViewGroup.LayoutParams.MATCH_PARENT; 79 private int mNormalWidth; 80 private int mPadding; 81 private int mMultiUserExpandedMargin; 82 private int mMultiUserCollapsedMargin; 83 private int mMultiUserKeyguardMargin; 84 private int mSystemIconsSwitcherHiddenExpandedMargin; 85 private int mClockMarginBottomExpanded; 86 private int mMultiUserSwitchWidthCollapsed; 87 private int mMultiUserSwitchWidthExpanded; 88 private int mBatteryPaddingEnd; 89 90 /** 91 * In collapsed QS, the clock and avatar are scaled down a bit post-layout to allow for a nice 92 * transition. These values determine that factor. 93 */ 94 private float mClockCollapsedScaleFactor; 95 private float mAvatarCollapsedScaleFactor; 96 97 private ActivityStarter mActivityStarter; 98 private BatteryController mBatteryController; 99 private QSPanel mQSPanel; 100 101 private final Rect mClipBounds = new Rect(); 102 private final StatusIconClipper mStatusIconClipper = new StatusIconClipper(); 103 104 public StatusBarHeaderView(Context context, AttributeSet attrs) { 105 super(context, attrs); 106 } 107 108 @Override 109 protected void onFinishInflate() { 110 super.onFinishInflate(); 111 mSystemIconsSuperContainer = findViewById(R.id.system_icons_super_container); 112 mSystemIconsContainer = (ViewGroup) findViewById(R.id.system_icons_container); 113 mSystemIconsSuperContainer.setOnClickListener(this); 114 mDateTime = findViewById(R.id.datetime); 115 mTime = findViewById(R.id.time_view); 116 mAmPm = findViewById(R.id.am_pm_view); 117 mKeyguardCarrierText = findViewById(R.id.keyguard_carrier_text); 118 mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch); 119 mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar); 120 mDateCollapsed = findViewById(R.id.date_collapsed); 121 mDateExpanded = findViewById(R.id.date_expanded); 122 mSettingsButton = findViewById(R.id.settings_button); 123 mSettingsButton.setOnClickListener(this); 124 mQsDetailHeader = findViewById(R.id.qs_detail_header); 125 mQsDetailHeader.setAlpha(0); 126 mQsDetailHeaderTitle = (TextView) mQsDetailHeader.findViewById(android.R.id.title); 127 mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle); 128 mEmergencyCallsOnly = findViewById(R.id.header_emergency_calls_only); 129 mBatteryLevel = (TextView) findViewById(R.id.battery_level); 130 loadDimens(); 131 updateVisibilities(); 132 updateClockScale(); 133 updateAvatarScale(); 134 addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 135 @Override 136 public void onLayoutChange(View v, int left, int top, int right, 137 int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 138 if ((right - left) != (oldRight - oldLeft)) { 139 // width changed, update clipping 140 setClipping(getHeight()); 141 } 142 boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 143 mTime.setPivotX(rtl ? mTime.getWidth() : 0); 144 mTime.setPivotY(mTime.getBaseline()); 145 mAmPm.setPivotX(rtl ? mAmPm.getWidth() : 0); 146 mAmPm.setPivotY(mAmPm.getBaseline()); 147 updateAmPmTranslation(); 148 } 149 }); 150 setOutlineProvider(new ViewOutlineProvider() { 151 @Override 152 public void getOutline(View view, Outline outline) { 153 outline.setRect(mClipBounds); 154 } 155 }); 156 } 157 158 private void loadDimens() { 159 mCollapsedHeight = getResources().getDimensionPixelSize(R.dimen.status_bar_header_height); 160 mExpandedHeight = getResources().getDimensionPixelSize( 161 R.dimen.status_bar_header_height_expanded); 162 mKeyguardHeight = getResources().getDimensionPixelSize( 163 R.dimen.status_bar_header_height_keyguard); 164 mNormalWidth = getLayoutParams().width; 165 mPadding = getResources().getDimensionPixelSize(R.dimen.notification_side_padding); 166 mMultiUserExpandedMargin = 167 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_expanded_margin); 168 mMultiUserCollapsedMargin = 169 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_collapsed_margin); 170 mMultiUserKeyguardMargin = 171 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_keyguard_margin); 172 mSystemIconsSwitcherHiddenExpandedMargin = getResources().getDimensionPixelSize( 173 R.dimen.system_icons_switcher_hidden_expanded_margin); 174 mClockMarginBottomExpanded = 175 getResources().getDimensionPixelSize(R.dimen.clock_expanded_bottom_margin); 176 mMultiUserSwitchWidthCollapsed = 177 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_width_collapsed); 178 mMultiUserSwitchWidthExpanded = 179 getResources().getDimensionPixelSize(R.dimen.multi_user_switch_width_expanded); 180 mAvatarCollapsedScaleFactor = 181 getResources().getDimensionPixelSize(R.dimen.multi_user_avatar_collapsed_size) 182 / (float) mMultiUserAvatar.getLayoutParams().width; 183 mClockCollapsedScaleFactor = 184 (float) getResources().getDimensionPixelSize(R.dimen.qs_time_collapsed_size) 185 / (float) getResources().getDimensionPixelSize(R.dimen.qs_time_expanded_size); 186 mBatteryPaddingEnd = 187 getResources().getDimensionPixelSize(R.dimen.battery_level_padding_end); 188 } 189 190 public void setActivityStarter(ActivityStarter activityStarter) { 191 mActivityStarter = activityStarter; 192 } 193 194 public void setBatteryController(BatteryController batteryController) { 195 mBatteryController = batteryController; 196 } 197 198 public int getCollapsedHeight() { 199 return mKeyguardShowing ? mKeyguardHeight : mCollapsedHeight; 200 } 201 202 public int getExpandedHeight() { 203 return mExpandedHeight; 204 } 205 206 public void setListening(boolean listening) { 207 if (listening == mListening) { 208 return; 209 } 210 mListening = listening; 211 updateBatteryListening(); 212 } 213 214 public void setExpanded(boolean expanded, boolean overscrolled) { 215 boolean changed = expanded != mExpanded; 216 boolean overscrollChanged = overscrolled != mOverscrolled; 217 mExpanded = expanded; 218 mOverscrolled = overscrolled; 219 if (changed || overscrollChanged) { 220 updateHeights(); 221 updateVisibilities(); 222 updateSystemIconsLayoutParams(); 223 updateZTranslation(); 224 updateClickTargets(); 225 updateWidth(); 226 updatePadding(); 227 updateMultiUserSwitch(); 228 if (mQSPanel != null) { 229 mQSPanel.setExpanded(expanded && !overscrolled); 230 } 231 updateClockScale(); 232 updateAvatarScale(); 233 updateClockLp(); 234 updateBatteryLevelPaddingEnd(); 235 mStatusIconClipper.update(); 236 } 237 } 238 239 private void updateHeights() { 240 boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded; 241 int height; 242 if (mExpanded) { 243 height = mExpandedHeight; 244 } else if (onKeyguardAndCollapsed) { 245 height = mKeyguardHeight; 246 } else { 247 height = mCollapsedHeight; 248 } 249 ViewGroup.LayoutParams lp = getLayoutParams(); 250 if (lp.height != height) { 251 lp.height = height; 252 setLayoutParams(lp); 253 } 254 int systemIconsContainerHeight = onKeyguardAndCollapsed ? mKeyguardHeight : mCollapsedHeight; 255 lp = mSystemIconsSuperContainer.getLayoutParams(); 256 if (lp.height != systemIconsContainerHeight) { 257 lp.height = systemIconsContainerHeight; 258 mSystemIconsSuperContainer.setLayoutParams(lp); 259 } 260 lp = mMultiUserSwitch.getLayoutParams(); 261 if (lp.height != systemIconsContainerHeight) { 262 lp.height = systemIconsContainerHeight; 263 mMultiUserSwitch.setLayoutParams(lp); 264 } 265 } 266 267 private void updateWidth() { 268 int width = (mKeyguardShowing && !mExpanded) ? mKeyguardWidth : mNormalWidth; 269 ViewGroup.LayoutParams lp = getLayoutParams(); 270 if (width != lp.width) { 271 lp.width = width; 272 setLayoutParams(lp); 273 } 274 } 275 276 private void updateVisibilities() { 277 boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded; 278 if (onKeyguardAndCollapsed) { 279 setBackground(null); 280 } else { 281 setBackgroundResource(R.drawable.notification_header_bg); 282 } 283 mDateTime.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE); 284 mKeyguardCarrierText.setVisibility(onKeyguardAndCollapsed ? View.VISIBLE : View.GONE); 285 mDateCollapsed.setVisibility(mExpanded && !mOverscrolled ? View.GONE : View.VISIBLE); 286 mDateExpanded.setVisibility(mExpanded && !mOverscrolled ? View.VISIBLE : View.GONE); 287 mSettingsButton.setVisibility(mExpanded && !mOverscrolled ? View.VISIBLE : View.GONE); 288 mQsDetailHeader.setVisibility(mExpanded ? View.VISIBLE : View.GONE); 289 if (mStatusIcons != null) { 290 mStatusIcons.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE); 291 } 292 if (mSignalCluster != null) { 293 mSignalCluster.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE); 294 } 295 mEmergencyCallsOnly.setVisibility(mExpanded && !mOverscrolled && mShowEmergencyCallsOnly 296 ? VISIBLE : GONE); 297 mMultiUserSwitch.setVisibility(mExpanded || !mKeyguardUserSwitcherShowing 298 ? VISIBLE : GONE); 299 mBatteryLevel.setVisibility(mKeyguardShowing && mCharging || mExpanded && !mOverscrolled 300 ? View.VISIBLE : View.GONE); 301 } 302 303 private void updateSystemIconsLayoutParams() { 304 RelativeLayout.LayoutParams lp = (LayoutParams) mSystemIconsSuperContainer.getLayoutParams(); 305 lp.addRule(RelativeLayout.START_OF, mExpanded && !mOverscrolled 306 ? mSettingsButton.getId() 307 : mMultiUserSwitch.getId()); 308 lp.removeRule(ALIGN_PARENT_START); 309 if (mMultiUserSwitch.getVisibility() == GONE) { 310 lp.setMarginEnd(mSystemIconsSwitcherHiddenExpandedMargin); 311 } else { 312 lp.setMarginEnd(0); 313 } 314 mSystemIconsSuperContainer.setLayoutParams(lp); 315 } 316 317 private void updateBatteryListening() { 318 if (mListening) { 319 mBatteryController.addStateChangedCallback(this); 320 } else { 321 mBatteryController.removeStateChangedCallback(this); 322 } 323 } 324 325 private void updateAvatarScale() { 326 if (!mExpanded || mOverscrolled) { 327 mMultiUserSwitch.setScaleX(mAvatarCollapsedScaleFactor); 328 mMultiUserSwitch.setScaleY(mAvatarCollapsedScaleFactor); 329 } else { 330 mMultiUserSwitch.setScaleX(1f); 331 mMultiUserSwitch.setScaleY(1f); 332 } 333 } 334 335 private void updateClockScale() { 336 mAmPm.setScaleX(mClockCollapsedScaleFactor); 337 mAmPm.setScaleY(mClockCollapsedScaleFactor); 338 if (!mExpanded || mOverscrolled) { 339 mTime.setScaleX(mClockCollapsedScaleFactor); 340 mTime.setScaleY(mClockCollapsedScaleFactor); 341 } else { 342 mTime.setScaleX(1f); 343 mTime.setScaleY(1f); 344 } 345 updateAmPmTranslation(); 346 } 347 348 private void updateAmPmTranslation() { 349 boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 350 mAmPm.setTranslationX((rtl ? 1 : -1) * mTime.getWidth() * (1 - mTime.getScaleX())); 351 } 352 353 private void updateBatteryLevelPaddingEnd() { 354 mBatteryLevel.setPaddingRelative(0, 0, 355 mKeyguardShowing && !mExpanded ? 0 : mBatteryPaddingEnd, 0); 356 } 357 358 @Override 359 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { 360 mBatteryLevel.setText(getResources().getString(R.string.battery_level_template, level)); 361 boolean changed = mCharging != charging; 362 mCharging = charging; 363 if (changed) { 364 updateVisibilities(); 365 } 366 } 367 368 @Override 369 public void onPowerSaveChanged() { 370 // could not care less 371 } 372 373 private void updateClickTargets() { 374 setClickable(!mKeyguardShowing || mExpanded); 375 mDateTime.setClickable(mExpanded); 376 mMultiUserSwitch.setClickable(mExpanded); 377 mSystemIconsSuperContainer.setClickable(mExpanded); 378 } 379 380 private void updateZTranslation() { 381 382 // If we are on the Keyguard, we need to set our z position to zero, so we don't get 383 // shadows. 384 if (mKeyguardShowing && !mExpanded) { 385 setZ(0); 386 } else { 387 setTranslationZ(0); 388 } 389 } 390 391 private void updatePadding() { 392 boolean padded = !mKeyguardShowing || mExpanded; 393 int padding = padded ? mPadding : 0; 394 setPaddingRelative(padding, 0, padding, 0); 395 } 396 397 private void updateClockLp() { 398 int marginBottom = mExpanded && !mOverscrolled ? mClockMarginBottomExpanded : 0; 399 LayoutParams lp = (LayoutParams) mDateTime.getLayoutParams(); 400 int rule = mExpanded && !mOverscrolled ? TRUE : 0; 401 if (marginBottom != lp.bottomMargin 402 || lp.getRules()[RelativeLayout.ALIGN_PARENT_BOTTOM] != rule) { 403 lp.bottomMargin = marginBottom; 404 lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, rule); 405 mDateTime.setLayoutParams(lp); 406 } 407 } 408 409 private void updateMultiUserSwitch() { 410 int marginEnd; 411 if (mExpanded && !mOverscrolled) { 412 marginEnd = mMultiUserExpandedMargin; 413 } else if (mKeyguardShowing) { 414 marginEnd = mMultiUserKeyguardMargin; 415 } else { 416 marginEnd = mMultiUserCollapsedMargin; 417 } 418 int width = mExpanded && !mOverscrolled 419 ? mMultiUserSwitchWidthExpanded 420 : mMultiUserSwitchWidthCollapsed; 421 MarginLayoutParams lp = (MarginLayoutParams) mMultiUserSwitch.getLayoutParams(); 422 if (marginEnd != lp.getMarginEnd() || lp.width != width) { 423 lp.setMarginEnd(marginEnd); 424 lp.width = width; 425 mMultiUserSwitch.setLayoutParams(lp); 426 } 427 } 428 429 public void setExpansion(float t) { 430 float height = mCollapsedHeight + t * (mExpandedHeight - mCollapsedHeight); 431 if (height < mCollapsedHeight) { 432 height = mCollapsedHeight; 433 } 434 if (height > mExpandedHeight) { 435 height = mExpandedHeight; 436 } 437 setClipping(height); 438 } 439 440 private void setClipping(float height) { 441 mClipBounds.set(getPaddingLeft(), 0, getWidth() - getPaddingRight(), (int) height); 442 setClipBounds(mClipBounds); 443 invalidateOutline(); 444 } 445 446 public void attachSystemIcons(LinearLayout systemIcons) { 447 mSystemIconsContainer.addView(systemIcons); 448 mStatusIcons = systemIcons.findViewById(R.id.statusIcons); 449 mSignalCluster = systemIcons.findViewById(R.id.signal_cluster); 450 mSignalCluster.addOnLayoutChangeListener(mStatusIconClipper); 451 } 452 453 public void onSystemIconsDetached() { 454 if (mStatusIcons != null) { 455 mStatusIcons.setVisibility(View.VISIBLE); 456 } 457 if (mSignalCluster != null) { 458 mSignalCluster.removeOnLayoutChangeListener(mStatusIconClipper); 459 mSignalCluster.setVisibility(View.VISIBLE); 460 } 461 mStatusIcons = null; 462 mSignalCluster = null; 463 } 464 465 public void setKeyguardShowing(boolean keyguardShowing) { 466 mKeyguardShowing = keyguardShowing; 467 updateHeights(); 468 updateWidth(); 469 updateVisibilities(); 470 updateZTranslation(); 471 updatePadding(); 472 updateMultiUserSwitch(); 473 updateClickTargets(); 474 updateBatteryLevelPaddingEnd(); 475 mStatusIconClipper.update(); 476 } 477 478 public void setUserInfoController(UserInfoController userInfoController) { 479 userInfoController.addListener(new UserInfoController.OnUserInfoChangedListener() { 480 @Override 481 public void onUserInfoChanged(String name, Drawable picture) { 482 mMultiUserAvatar.setImageDrawable(picture); 483 } 484 }); 485 } 486 487 @Override 488 public void onClick(View v) { 489 if (v == mSettingsButton) { 490 startSettingsActivity(); 491 } else if (v == mSystemIconsSuperContainer) { 492 startBatteryActivity(); 493 } 494 } 495 496 private void startSettingsActivity() { 497 mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS)); 498 } 499 500 private void startBatteryActivity() { 501 mActivityStarter.startActivity(new Intent(Intent.ACTION_POWER_USAGE_SUMMARY)); 502 } 503 504 public void setQSPanel(QSPanel qsp) { 505 mQSPanel = qsp; 506 if (mQSPanel != null) { 507 mQSPanel.setCallback(mQsPanelCallback); 508 } 509 mMultiUserSwitch.setQsPanel(qsp); 510 } 511 512 @Override 513 public boolean shouldDelayChildPressedState() { 514 return true; 515 } 516 517 public void setShowEmergencyCallsOnly(boolean show) { 518 mShowEmergencyCallsOnly = show; 519 if (mExpanded) { 520 updateVisibilities(); 521 } 522 } 523 524 public void setKeyguardUserSwitcherShowing(boolean showing) { 525 // STOPSHIP: NOT CALLED PROPERLY WHEN GOING TO FULL SHADE AND RETURNING!?! 526 mKeyguardUserSwitcherShowing = showing; 527 updateVisibilities(); 528 updateSystemIconsLayoutParams(); 529 } 530 531 @Override 532 public boolean hasOverlappingRendering() { 533 return !mKeyguardShowing || mExpanded; 534 } 535 536 @Override 537 protected void dispatchSetPressed(boolean pressed) { 538 // We don't want that everything lights up when we click on the header, so block the request 539 // here. 540 } 541 542 private final class StatusIconClipper implements OnLayoutChangeListener { 543 private final Rect mClipBounds = new Rect(); 544 545 @Override 546 public void onLayoutChange(View v, int left, int top, int right, 547 int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 548 // Hide the statusIcons in the header by clipping them. Can't touch visibility since 549 // they are mirrored to the real status bar. 550 mClipBounds.set(left, 0, mSystemIconsContainer.getWidth(), 551 mSystemIconsContainer.getHeight()); 552 update(); 553 } 554 555 public void update() { 556 final boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded; 557 mSystemIconsContainer.setClipBounds(onKeyguardAndCollapsed ? null : mClipBounds); 558 } 559 } 560 561 private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() { 562 @Override 563 public void onToggleStateChanged(final boolean state) { 564 post(new Runnable() { 565 @Override 566 public void run() { 567 handleToggleStateChanged(state); 568 } 569 }); 570 } 571 572 @Override 573 public void onShowingDetail(final QSTile.DetailAdapter detail) { 574 post(new Runnable() { 575 @Override 576 public void run() { 577 handleShowingDetail(detail); 578 } 579 }); 580 } 581 582 @Override 583 public void onScanStateChanged(final boolean state) { 584 post(new Runnable() { 585 @Override 586 public void run() { 587 handleScanStateChanged(state); 588 } 589 }); 590 } 591 592 private void handleToggleStateChanged(boolean state) { 593 mQsDetailHeaderSwitch.setChecked(state); 594 } 595 596 private void handleScanStateChanged(boolean state) { 597 // TODO - waiting on framework asset 598 } 599 600 private void handleShowingDetail(final QSTile.DetailAdapter detail) { 601 final boolean showingDetail = detail != null; 602 transition(mDateTime, !showingDetail); 603 transition(mQsDetailHeader, showingDetail); 604 if (showingDetail) { 605 mQsDetailHeaderTitle.setText(detail.getTitle()); 606 final Boolean toggleState = detail.getToggleState(); 607 if (toggleState == null) { 608 mQsDetailHeaderSwitch.setVisibility(INVISIBLE); 609 mQsDetailHeader.setClickable(false); 610 } else { 611 mQsDetailHeaderSwitch.setVisibility(VISIBLE); 612 mQsDetailHeaderSwitch.setChecked(toggleState); 613 mQsDetailHeader.setClickable(true); 614 mQsDetailHeader.setOnClickListener(new OnClickListener() { 615 @Override 616 public void onClick(View v) { 617 detail.setToggleState(!mQsDetailHeaderSwitch.isChecked()); 618 } 619 }); 620 } 621 } else { 622 mQsDetailHeader.setClickable(false); 623 } 624 } 625 626 private void transition(final View v, final boolean in) { 627 if (in) { 628 v.bringToFront(); 629 } 630 v.animate().alpha(in ? 1 : 0).withLayer().start(); 631 } 632 }; 633} 634