From b96069936c4e6d10c119efa9943fba818b09373e Mon Sep 17 00:00:00 2001 From: Daniel Sandler Date: Fri, 19 Nov 2010 14:47:59 -0500 Subject: Improve hide/show animations in status bar. This cleans up the lights out experience so you can clearly see that the "shadows" along the bottom of the bar correspond to invisible (but still available) UI elements. Bug: 3203171 Change-Id: I635394d625bf97bbbe7260c1ae9320b616ea7aec --- packages/SystemUI/res/layout-xlarge/status_bar.xml | 117 +++++++-------- .../systemui/statusbar/tablet/TabletStatusBar.java | 158 +++++++++++++-------- 2 files changed, 158 insertions(+), 117 deletions(-) (limited to 'packages') diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml index d4a6136..d11e6da 100644 --- a/packages/SystemUI/res/layout-xlarge/status_bar.xml +++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml @@ -25,7 +25,6 @@ android:id="@+id/bar_contents" android:layout_width="match_parent" android:layout_height="match_parent" - android:animateLayoutChanges="false" > @@ -105,7 +104,6 @@ android:layout_height="match_parent" android:layout_alignParentLeft="true" android:orientation="horizontal" - android:animateLayoutChanges="false" > - + > + - - - - + + + + + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index 7c97ac7..233ac45 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -19,9 +19,12 @@ package com.android.systemui.statusbar.tablet; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Map; +import java.util.IdentityHashMap; import android.animation.LayoutTransition; import android.animation.ObjectAnimator; +import android.animation.AnimatorSet; import android.app.ActivityManagerNative; import android.app.PendingIntent; import android.app.Notification; @@ -257,21 +260,6 @@ public class TabletStatusBar extends StatusBar { mBarContents = sb.findViewById(R.id.bar_contents); - // "shadows" of the status bar features, for lights-out mode - mBackShadow = sb.findViewById(R.id.back_shadow); - mHomeShadow = sb.findViewById(R.id.home_shadow); - mRecentShadow = sb.findViewById(R.id.recent_shadow); - mMenuShadow = sb.findViewById(R.id.menu_shadow); - mNotificationShadow = sb.findViewById(R.id.notification_shadow); - - mShadowController = new ShadowController(false); - - mBackShadow.setOnTouchListener(mShadowController.makeTouchListener()); - mHomeShadow.setOnTouchListener(mShadowController.makeTouchListener()); - mRecentShadow.setOnTouchListener(mShadowController.makeTouchListener()); - mMenuShadow.setOnTouchListener(mShadowController.makeTouchListener()); - mNotificationShadow.setOnTouchListener(mShadowController.makeTouchListener()); - // the whole right-hand side of the bar mNotificationArea = sb.findViewById(R.id.notificationArea); @@ -310,6 +298,20 @@ public class TabletStatusBar extends StatusBar { // The bar contents buttons mInputMethodButton = (InputMethodButton) sb.findViewById(R.id.imeButton); + // "shadows" of the status bar features, for lights-out mode + mBackShadow = sb.findViewById(R.id.back_shadow); + mHomeShadow = sb.findViewById(R.id.home_shadow); + mRecentShadow = sb.findViewById(R.id.recent_shadow); + mMenuShadow = sb.findViewById(R.id.menu_shadow); + mNotificationShadow = sb.findViewById(R.id.notification_shadow); + + mShadowController = new ShadowController(false); + mShadowController.add(mBackButton, mBackShadow); + mShadowController.add(mHomeButton, mHomeShadow); + mShadowController.add(mRecentButton, mRecentShadow); + mShadowController.add(mMenuButton, mMenuShadow); + mShadowController.add(mNotificationArea, mNotificationShadow); + // set the initial view visibility setAreThereNotifications(); refreshNotificationTrigger(); @@ -386,8 +388,8 @@ public class TabletStatusBar extends StatusBar { mNotificationPanel.setVisibility(View.VISIBLE); - // XXX: need to synchronize with shadows here - mNotificationArea.setVisibility(View.GONE); + // synchronize with current shadow state + mShadowController.hideElement(mNotificationArea); } break; case MSG_CLOSE_NOTIFICATION_PANEL: @@ -395,8 +397,8 @@ public class TabletStatusBar extends StatusBar { if (mNotificationPanel.getVisibility() == View.VISIBLE) { mNotificationPanel.setVisibility(View.GONE); - // XXX: need to synchronize with shadows here - mNotificationArea.setVisibility(View.VISIBLE); + // synchronize with current shadow state + mShadowController.showElement(mNotificationArea); } break; case MSG_OPEN_RECENTS_PANEL: @@ -576,11 +578,13 @@ public class TabletStatusBar extends StatusBar { if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes"); - mNotificationIconArea.setVisibility(View.GONE); + // synchronize with current shadow state + mShadowController.hideElement(mNotificationArea); mTicker.halt(); } else { Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no"); - mNotificationIconArea.setVisibility(View.VISIBLE); + // synchronize with current shadow state + mShadowController.showElement(mNotificationArea); } } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { if ((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { @@ -1047,11 +1051,57 @@ public class TabletStatusBar extends StatusBar { public class ShadowController { boolean mShowShadows; + Map mShadowsForElements = new IdentityHashMap(7); + Map mElementsForShadows = new IdentityHashMap(7); + LayoutTransition mElementTransition, mShadowTransition; + View mTouchTarget; ShadowController(boolean showShadows) { mShowShadows = showShadows; mTouchTarget = null; + + mElementTransition = new LayoutTransition(); +// AnimatorSet s = new AnimatorSet(); +// s.play(ObjectAnimator.ofInt(null, "top", 48, 0)) +// .with(ObjectAnimator.ofFloat(null, "scaleY", 0.5f, 1f)) +// .with(ObjectAnimator.ofFloat(null, "alpha", 0.5f, 1f)) +// ; + mElementTransition.setAnimator(LayoutTransition.APPEARING, //s); + ObjectAnimator.ofInt(null, "top", 48, 0)); + mElementTransition.setDuration(LayoutTransition.APPEARING, 100); + mElementTransition.setStartDelay(LayoutTransition.APPEARING, 0); + +// s = new AnimatorSet(); +// s.play(ObjectAnimator.ofInt(null, "top", 0, 48)) +// .with(ObjectAnimator.ofFloat(null, "scaleY", 1f, 0.5f)) +// .with(ObjectAnimator.ofFloat(null, "alpha", 1f, 0.5f)) +// ; + mElementTransition.setAnimator(LayoutTransition.DISAPPEARING, //s); + ObjectAnimator.ofInt(null, "top", 0, 48)); + mElementTransition.setDuration(LayoutTransition.DISAPPEARING, 400); + + mShadowTransition = new LayoutTransition(); + mShadowTransition.setAnimator(LayoutTransition.APPEARING, + ObjectAnimator.ofFloat(null, "alpha", 0f, 1f)); + mShadowTransition.setDuration(LayoutTransition.APPEARING, 200); + mShadowTransition.setStartDelay(LayoutTransition.APPEARING, 100); + mShadowTransition.setAnimator(LayoutTransition.DISAPPEARING, + ObjectAnimator.ofFloat(null, "alpha", 1f, 0f)); + mShadowTransition.setDuration(LayoutTransition.DISAPPEARING, 100); + + ViewGroup bar = (ViewGroup) TabletStatusBar.this.mBarContents; + bar.setLayoutTransition(mElementTransition); + ViewGroup nav = (ViewGroup) TabletStatusBar.this.mNavigationArea; + nav.setLayoutTransition(mElementTransition); + ViewGroup shadowGroup = (ViewGroup) bar.findViewById(R.id.shadows); + shadowGroup.setLayoutTransition(mShadowTransition); + } + + public void add(View element, View shadow) { + shadow.setOnTouchListener(makeTouchListener()); + mShadowsForElements.put(element, shadow); + mElementsForShadows.put(shadow, element); } public boolean getShadowState() { @@ -1067,17 +1117,7 @@ public class TabletStatusBar extends StatusBar { // currently redirecting events? if (mTouchTarget == null) { - if (v == mBackShadow) { - mTouchTarget = mBackButton; - } else if (v == mHomeShadow) { - mTouchTarget = mHomeButton; - } else if (v == mMenuShadow) { - mTouchTarget = mMenuButton; - } else if (v == mRecentShadow) { - mTouchTarget = mRecentButton; - } else if (v == mNotificationShadow) { - mTouchTarget = mNotificationArea; - } + mTouchTarget = mElementsForShadows.get(v); } if (mTouchTarget != null && mTouchTarget.getVisibility() != View.GONE) { @@ -1094,7 +1134,7 @@ public class TabletStatusBar extends StatusBar { break; case MotionEvent.ACTION_DOWN: mHandler.removeMessages(MSG_RESTORE_SHADOWS); - setShadowForButton(mTouchTarget, false); + setElementShadow(mTouchTarget, false); break; } mTouchTarget.dispatchTouchEvent(ev); @@ -1108,11 +1148,9 @@ public class TabletStatusBar extends StatusBar { } public void refresh() { - setShadowForButton(mBackButton, mShowShadows); - setShadowForButton(mHomeButton, mShowShadows); - setShadowForButton(mRecentButton, mShowShadows); - setShadowForButton(mMenuButton, mShowShadows); - setShadowForButton(mNotificationArea, mShowShadows); + for (View element : mShadowsForElements.keySet()) { + setElementShadow(element, mShowShadows); + } } public void showAllShadows() { @@ -1127,19 +1165,8 @@ public class TabletStatusBar extends StatusBar { // Use View.INVISIBLE for things hidden due to shadowing, and View.GONE for things that are // disabled (and should not be shadowed or re-shown) - public void setShadowForButton(View button, boolean shade) { - View shadow = null; - if (button == mBackButton) { - shadow = mBackShadow; - } else if (button == mHomeButton) { - shadow = mHomeShadow; - } else if (button == mMenuButton) { - shadow = mMenuShadow; - } else if (button == mRecentButton) { - shadow = mRecentShadow; - } else if (button == mNotificationArea) { - shadow = mNotificationShadow; - } + public void setElementShadow(View button, boolean shade) { + View shadow = mShadowsForElements.get(button); if (shadow != null) { if (button.getVisibility() != View.GONE) { shadow.setVisibility(shade ? View.VISIBLE : View.INVISIBLE); @@ -1147,6 +1174,26 @@ public class TabletStatusBar extends StatusBar { } } } + + // Hide both element and shadow, using default layout animations. + public void hideElement(View button) { + Slog.d(TAG, "hiding: " + button); + View shadow = mShadowsForElements.get(button); + if (shadow != null) { + shadow.setVisibility(View.GONE); + } + button.setVisibility(View.GONE); + } + + // Honoring the current shadow state. + public void showElement(View button) { + Slog.d(TAG, "showing: " + button); + View shadow = mShadowsForElements.get(button); + if (shadow != null) { + shadow.setVisibility(mShowShadows ? View.VISIBLE : View.INVISIBLE); + } + button.setVisibility(mShowShadows ? View.INVISIBLE : View.VISIBLE); + } } public class TouchOutsideListener implements View.OnTouchListener { @@ -1171,15 +1218,6 @@ public class TabletStatusBar extends StatusBar { } } - private void setViewVisibility(View v, int vis, int anim) { - if (v.getVisibility() != vis) { - //Slog.d(TAG, "setViewVisibility vis=" + (vis == View.VISIBLE) + " v=" + v); - v.setAnimation(AnimationUtils.loadAnimation(mContext, anim)); - v.setVisibility(vis); - } - } - - public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.print("mDisabled=0x"); pw.println(Integer.toHexString(mDisabled)); -- cgit v1.1