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