StatusBarHeaderView.java revision 604ae091429f3ade44daaed25014ee7fbb35bcff
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 103 public StatusBarHeaderView(Context context, AttributeSet attrs) { 104 super(context, attrs); 105 } 106 107 @Override 108 protected void onFinishInflate() { 109 super.onFinishInflate(); 110 mSystemIconsSuperContainer = findViewById(R.id.system_icons_super_container); 111 mSystemIconsContainer = (ViewGroup) findViewById(R.id.system_icons_container); 112 mSystemIconsSuperContainer.setOnClickListener(this); 113 mDateTime = findViewById(R.id.datetime); 114 mTime = findViewById(R.id.time_view); 115 mAmPm = findViewById(R.id.am_pm_view); 116 mKeyguardCarrierText = findViewById(R.id.keyguard_carrier_text); 117 mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch); 118 mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar); 119 mDateCollapsed = findViewById(R.id.date_collapsed); 120 mDateExpanded = findViewById(R.id.date_expanded); 121 mSettingsButton = findViewById(R.id.settings_button); 122 mSettingsButton.setOnClickListener(this); 123 mQsDetailHeader = findViewById(R.id.qs_detail_header); 124 mQsDetailHeader.setAlpha(0); 125 mQsDetailHeaderTitle = (TextView) mQsDetailHeader.findViewById(android.R.id.title); 126 mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle); 127 mEmergencyCallsOnly = findViewById(R.id.header_emergency_calls_only); 128 mBatteryLevel = (TextView) findViewById(R.id.battery_level); 129 loadDimens(); 130 updateVisibilities(); 131 updateClockScale(); 132 updateAvatarScale(); 133 addOnLayoutChangeListener(new View.OnLayoutChangeListener() { 134 @Override 135 public void onLayoutChange(View v, int left, int top, int right, 136 int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 137 if ((right - left) != (oldRight - oldLeft)) { 138 // width changed, update clipping 139 setClipping(getHeight()); 140 } 141 boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 142 mTime.setPivotX(rtl ? mTime.getWidth() : 0); 143 mTime.setPivotY(mTime.getBaseline()); 144 mAmPm.setPivotX(rtl ? mAmPm.getWidth() : 0); 145 mAmPm.setPivotY(mAmPm.getBaseline()); 146 updateAmPmTranslation(); 147 } 148 }); 149 setOutlineProvider(new ViewOutlineProvider() { 150 @Override 151 public boolean getOutline(View view, Outline outline) { 152 outline.setRect(mClipBounds); 153 return true; 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 } 236 } 237 238 private void updateHeights() { 239 boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded; 240 int height; 241 if (mExpanded) { 242 height = mExpandedHeight; 243 } else if (onKeyguardAndCollapsed) { 244 height = mKeyguardHeight; 245 } else { 246 height = mCollapsedHeight; 247 } 248 ViewGroup.LayoutParams lp = getLayoutParams(); 249 if (lp.height != height) { 250 lp.height = height; 251 setLayoutParams(lp); 252 } 253 int systemIconsContainerHeight = onKeyguardAndCollapsed ? mKeyguardHeight : mCollapsedHeight; 254 lp = mSystemIconsSuperContainer.getLayoutParams(); 255 if (lp.height != systemIconsContainerHeight) { 256 lp.height = systemIconsContainerHeight; 257 mSystemIconsSuperContainer.setLayoutParams(lp); 258 } 259 lp = mMultiUserSwitch.getLayoutParams(); 260 if (lp.height != systemIconsContainerHeight) { 261 lp.height = systemIconsContainerHeight; 262 mMultiUserSwitch.setLayoutParams(lp); 263 } 264 } 265 266 private void updateWidth() { 267 int width = (mKeyguardShowing && !mExpanded) ? mKeyguardWidth : mNormalWidth; 268 ViewGroup.LayoutParams lp = getLayoutParams(); 269 if (width != lp.width) { 270 lp.width = width; 271 setLayoutParams(lp); 272 } 273 } 274 275 private void updateVisibilities() { 276 boolean onKeyguardAndCollapsed = mKeyguardShowing && !mExpanded; 277 if (onKeyguardAndCollapsed) { 278 setBackground(null); 279 } else { 280 setBackgroundResource(R.drawable.notification_header_bg); 281 } 282 mDateTime.setVisibility(onKeyguardAndCollapsed ? View.INVISIBLE : View.VISIBLE); 283 mKeyguardCarrierText.setVisibility(onKeyguardAndCollapsed ? View.VISIBLE : View.GONE); 284 mDateCollapsed.setVisibility(mExpanded && !mOverscrolled ? View.GONE : View.VISIBLE); 285 mDateExpanded.setVisibility(mExpanded && !mOverscrolled ? View.VISIBLE : View.GONE); 286 mSettingsButton.setVisibility(mExpanded && !mOverscrolled ? View.VISIBLE : View.GONE); 287 mQsDetailHeader.setVisibility(mExpanded ? View.VISIBLE : View.GONE); 288 if (mStatusIcons != null) { 289 mStatusIcons.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE); 290 } 291 if (mSignalCluster != null) { 292 mSignalCluster.setVisibility(!mExpanded || mOverscrolled ? View.VISIBLE : View.GONE); 293 } 294 mEmergencyCallsOnly.setVisibility(mExpanded && !mOverscrolled && mShowEmergencyCallsOnly 295 ? VISIBLE : GONE); 296 mMultiUserSwitch.setVisibility(mExpanded || !mKeyguardUserSwitcherShowing 297 ? VISIBLE : GONE); 298 mBatteryLevel.setVisibility(mKeyguardShowing && mCharging || mExpanded && !mOverscrolled 299 ? View.VISIBLE : View.GONE); 300 } 301 302 private void updateSystemIconsLayoutParams() { 303 RelativeLayout.LayoutParams lp = (LayoutParams) mSystemIconsSuperContainer.getLayoutParams(); 304 lp.addRule(RelativeLayout.START_OF, mExpanded && !mOverscrolled 305 ? mSettingsButton.getId() 306 : mMultiUserSwitch.getId()); 307 lp.removeRule(ALIGN_PARENT_START); 308 if (mMultiUserSwitch.getVisibility() == GONE) { 309 lp.setMarginEnd(mSystemIconsSwitcherHiddenExpandedMargin); 310 } else { 311 lp.setMarginEnd(0); 312 } 313 mSystemIconsSuperContainer.setLayoutParams(lp); 314 } 315 316 private void updateBatteryListening() { 317 if (mListening) { 318 mBatteryController.addStateChangedCallback(this); 319 } else { 320 mBatteryController.removeStateChangedCallback(this); 321 } 322 } 323 324 private void updateAvatarScale() { 325 if (!mExpanded || mOverscrolled) { 326 mMultiUserSwitch.setScaleX(mAvatarCollapsedScaleFactor); 327 mMultiUserSwitch.setScaleY(mAvatarCollapsedScaleFactor); 328 } else { 329 mMultiUserSwitch.setScaleX(1f); 330 mMultiUserSwitch.setScaleY(1f); 331 } 332 } 333 334 private void updateClockScale() { 335 mAmPm.setScaleX(mClockCollapsedScaleFactor); 336 mAmPm.setScaleY(mClockCollapsedScaleFactor); 337 if (!mExpanded || mOverscrolled) { 338 mTime.setScaleX(mClockCollapsedScaleFactor); 339 mTime.setScaleY(mClockCollapsedScaleFactor); 340 } else { 341 mTime.setScaleX(1f); 342 mTime.setScaleY(1f); 343 } 344 updateAmPmTranslation(); 345 } 346 347 private void updateAmPmTranslation() { 348 boolean rtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; 349 mAmPm.setTranslationX((rtl ? 1 : -1) * mTime.getWidth() * (1 - mTime.getScaleX())); 350 } 351 352 private void updateBatteryLevelPaddingEnd() { 353 mBatteryLevel.setPaddingRelative(0, 0, 354 mKeyguardShowing && !mExpanded ? 0 : mBatteryPaddingEnd, 0); 355 } 356 357 @Override 358 public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) { 359 mBatteryLevel.setText(getResources().getString(R.string.battery_level_template, level)); 360 boolean changed = mCharging != charging; 361 mCharging = charging; 362 if (changed) { 363 updateVisibilities(); 364 } 365 } 366 367 private void updateClickTargets() { 368 setClickable(!mKeyguardShowing || mExpanded); 369 mDateTime.setClickable(mExpanded); 370 mMultiUserSwitch.setClickable(mExpanded); 371 mSystemIconsSuperContainer.setClickable(mExpanded); 372 } 373 374 private void updateZTranslation() { 375 376 // If we are on the Keyguard, we need to set our z position to zero, so we don't get 377 // shadows. 378 if (mKeyguardShowing && !mExpanded) { 379 setZ(0); 380 } else { 381 setTranslationZ(0); 382 } 383 } 384 385 private void updatePadding() { 386 boolean padded = !mKeyguardShowing || mExpanded; 387 int padding = padded ? mPadding : 0; 388 setPaddingRelative(padding, 0, padding, 0); 389 } 390 391 private void updateClockLp() { 392 int marginBottom = mExpanded && !mOverscrolled ? mClockMarginBottomExpanded : 0; 393 LayoutParams lp = (LayoutParams) mDateTime.getLayoutParams(); 394 int rule = mExpanded && !mOverscrolled ? TRUE : 0; 395 if (marginBottom != lp.bottomMargin 396 || lp.getRules()[RelativeLayout.ALIGN_PARENT_BOTTOM] != rule) { 397 lp.bottomMargin = marginBottom; 398 lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, rule); 399 mDateTime.setLayoutParams(lp); 400 } 401 } 402 403 private void updateMultiUserSwitch() { 404 int marginEnd; 405 if (mExpanded && !mOverscrolled) { 406 marginEnd = mMultiUserExpandedMargin; 407 } else if (mKeyguardShowing) { 408 marginEnd = mMultiUserKeyguardMargin; 409 } else { 410 marginEnd = mMultiUserCollapsedMargin; 411 } 412 int width = mExpanded && !mOverscrolled 413 ? mMultiUserSwitchWidthExpanded 414 : mMultiUserSwitchWidthCollapsed; 415 MarginLayoutParams lp = (MarginLayoutParams) mMultiUserSwitch.getLayoutParams(); 416 if (marginEnd != lp.getMarginEnd() || lp.width != width) { 417 lp.setMarginEnd(marginEnd); 418 lp.width = width; 419 mMultiUserSwitch.setLayoutParams(lp); 420 } 421 } 422 423 public void setExpansion(float t) { 424 float height = mCollapsedHeight + t * (mExpandedHeight - mCollapsedHeight); 425 if (height < mCollapsedHeight) { 426 height = mCollapsedHeight; 427 } 428 if (height > mExpandedHeight) { 429 height = mExpandedHeight; 430 } 431 setClipping(height); 432 } 433 434 private void setClipping(float height) { 435 mClipBounds.set(getPaddingLeft(), 0, getWidth() - getPaddingRight(), (int) height); 436 setClipBounds(mClipBounds); 437 invalidateOutline(); 438 } 439 440 public void attachSystemIcons(LinearLayout systemIcons) { 441 mSystemIconsContainer.addView(systemIcons); 442 mStatusIcons = systemIcons.findViewById(R.id.statusIcons); 443 mSignalCluster = systemIcons.findViewById(R.id.signal_cluster); 444 mSignalCluster.addOnLayoutChangeListener(mSignalClusterChanged); 445 } 446 447 public void onSystemIconsDetached() { 448 if (mStatusIcons != null) { 449 mStatusIcons.setVisibility(View.VISIBLE); 450 } 451 if (mSignalCluster != null) { 452 mSignalCluster.removeOnLayoutChangeListener(mSignalClusterChanged); 453 mSignalCluster.setVisibility(View.VISIBLE); 454 } 455 mStatusIcons = null; 456 mSignalCluster = null; 457 } 458 459 public void setKeyguardShowing(boolean keyguardShowing) { 460 mKeyguardShowing = keyguardShowing; 461 updateHeights(); 462 updateWidth(); 463 updateVisibilities(); 464 updateZTranslation(); 465 updatePadding(); 466 updateMultiUserSwitch(); 467 updateClickTargets(); 468 updateBatteryLevelPaddingEnd(); 469 } 470 471 public void setUserInfoController(UserInfoController userInfoController) { 472 userInfoController.addListener(new UserInfoController.OnUserInfoChangedListener() { 473 @Override 474 public void onUserInfoChanged(String name, Drawable picture) { 475 mMultiUserAvatar.setImageDrawable(picture); 476 } 477 }); 478 } 479 480 @Override 481 public void onClick(View v) { 482 if (v == mSettingsButton) { 483 startSettingsActivity(); 484 } else if (v == mSystemIconsSuperContainer) { 485 startBatteryActivity(); 486 } 487 } 488 489 private void startSettingsActivity() { 490 mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS)); 491 } 492 493 private void startBatteryActivity() { 494 mActivityStarter.startActivity(new Intent(Intent.ACTION_POWER_USAGE_SUMMARY)); 495 } 496 497 public void setQSPanel(QSPanel qsp) { 498 mQSPanel = qsp; 499 if (mQSPanel != null) { 500 mQSPanel.setCallback(mQsPanelCallback); 501 } 502 mMultiUserSwitch.setQsPanel(qsp); 503 } 504 505 @Override 506 public boolean shouldDelayChildPressedState() { 507 return true; 508 } 509 510 public void setShowEmergencyCallsOnly(boolean show) { 511 mShowEmergencyCallsOnly = show; 512 if (mExpanded) { 513 updateVisibilities(); 514 } 515 } 516 517 public void setKeyguardUserSwitcherShowing(boolean showing) { 518 // STOPSHIP: NOT CALLED PROPERLY WHEN GOING TO FULL SHADE AND RETURNING!?! 519 mKeyguardUserSwitcherShowing = showing; 520 updateVisibilities(); 521 updateSystemIconsLayoutParams(); 522 } 523 524 @Override 525 public boolean hasOverlappingRendering() { 526 return !mKeyguardShowing || mExpanded; 527 } 528 529 @Override 530 protected void dispatchSetPressed(boolean pressed) { 531 // We don't want that everything lights up when we click on the header, so block the request 532 // here. 533 } 534 535 private final OnLayoutChangeListener mSignalClusterChanged = new OnLayoutChangeListener() { 536 private final Rect mClipBounds = new Rect(); 537 538 @Override 539 public void onLayoutChange(View v, int left, int top, int right, 540 int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 541 // Hide the statusIcons in the header by clipping them. Can't touch visibility since 542 // they are mirrored to the real status bar. 543 mClipBounds.set(left, 0, mSystemIconsContainer.getWidth(), 544 mSystemIconsContainer.getHeight()); 545 mSystemIconsContainer.setClipBounds(mClipBounds); 546 } 547 }; 548 549 private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() { 550 @Override 551 public void onToggleStateChanged(final boolean state) { 552 post(new Runnable() { 553 @Override 554 public void run() { 555 handleToggleStateChanged(state); 556 } 557 }); 558 } 559 560 @Override 561 public void onShowingDetail(final QSTile.DetailAdapter detail) { 562 post(new Runnable() { 563 @Override 564 public void run() { 565 handleShowingDetail(detail); 566 } 567 }); 568 } 569 570 @Override 571 public void onScanStateChanged(final boolean state) { 572 post(new Runnable() { 573 @Override 574 public void run() { 575 handleScanStateChanged(state); 576 } 577 }); 578 } 579 580 private void handleToggleStateChanged(boolean state) { 581 mQsDetailHeaderSwitch.setChecked(state); 582 } 583 584 private void handleScanStateChanged(boolean state) { 585 // TODO - waiting on framework asset 586 } 587 588 private void handleShowingDetail(final QSTile.DetailAdapter detail) { 589 final boolean showingDetail = detail != null; 590 transition(mDateTime, !showingDetail); 591 transition(mQsDetailHeader, showingDetail); 592 if (showingDetail) { 593 mQsDetailHeaderTitle.setText(detail.getTitle()); 594 final Boolean toggleState = detail.getToggleState(); 595 if (toggleState == null) { 596 mQsDetailHeaderSwitch.setVisibility(INVISIBLE); 597 mQsDetailHeader.setClickable(false); 598 } else { 599 mQsDetailHeaderSwitch.setVisibility(VISIBLE); 600 mQsDetailHeaderSwitch.setChecked(toggleState); 601 mQsDetailHeader.setClickable(true); 602 mQsDetailHeader.setOnClickListener(new OnClickListener() { 603 @Override 604 public void onClick(View v) { 605 detail.setToggleState(!mQsDetailHeaderSwitch.isChecked()); 606 } 607 }); 608 } 609 } else { 610 mQsDetailHeader.setClickable(false); 611 } 612 } 613 614 private void transition(final View v, final boolean in) { 615 if (in) { 616 v.bringToFront(); 617 } 618 v.animate().alpha(in ? 1 : 0).withLayer().start(); 619 } 620 }; 621} 622