From 173bae2c674b2bc25cf376cbb4e150bd86703049 Mon Sep 17 00:00:00 2001 From: Daniel Sandler Date: Tue, 25 Sep 2012 14:37:42 -0400 Subject: [PATCH] Improvements to notification/settings panels: A) Hide icons corresponding to the active panel with a downward push animation. Notes: 1. this animation will now apply any time the status bar icons are disabled via DISABLE_NOTIFICATION_ICONS. 2. DISABLE_SYSTEM_INFO will now only hide the right hand icons (system status icons, battery, clock). But you weren't using it anyway, right? B) Stop pulling down the panels in response to just a touch on the status bar. (That should never have worked.) In general, we now require that a fling proceed more than 10dp to be treated as a fling with velocity (as opposed to a v=0 fling, or "let-go"). C) If a panel is pulled down more than halfway and then let go with v=0, it is expanded. If less than halfway, it is contracted. (Helps fix B) above, plus it just makes good sense.) Bug: 7211541 (A) Bug: 7227237 (B) Bug: 7228541 (B) Change-Id: I5662269b753376804bf629239835dc212716d5c3 --- packages/SystemUI/res/layout/status_bar.xml | 70 ++++----- packages/SystemUI/res/values/dimens.xml | 3 + .../systemui/statusbar/phone/PanelBar.java | 8 ++ .../systemui/statusbar/phone/PanelView.java | 29 +++- .../statusbar/phone/PhoneStatusBar.java | 134 +++++++----------- 5 files changed, 125 insertions(+), 119 deletions(-) diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml index 6ed5fb775afeb..bf20e9dbdec29 100644 --- a/packages/SystemUI/res/layout/status_bar.xml +++ b/packages/SystemUI/res/layout/status_bar.xml @@ -35,13 +35,13 @@ android:layout_width="@dimen/status_bar_icon_size" android:layout_height="match_parent" android:paddingLeft="6dip" - android:paddingBottom="2dip" + android:paddingBottom="2dip" android:src="@drawable/ic_sysbar_lights_out_dot_small" android:scaleType="center" android:visibility="gone" /> - - + android:orientation="horizontal"> - - - + + + + + + + - - 3000dp + + 10dp + 10% diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java index 9a3648fea67e0..f6236924576b7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -6,6 +6,7 @@ import android.content.Context; import android.util.AttributeSet; import android.util.Slog; import android.view.MotionEvent; +import android.view.View; import android.widget.FrameLayout; public class PanelBar extends FrameLayout { @@ -101,6 +102,7 @@ public class PanelBar extends FrameLayout { PanelView fullyOpenedPanel = null; LOG("panelExpansionChanged: start state=%d panel=%s", mState, panel.getName()); for (PanelView pv : mPanels) { + final boolean visible = pv.getVisibility() == View.VISIBLE; // adjust any other panels that may be partially visible if (pv.getExpandedHeight() > 0f) { if (mState == STATE_CLOSED) { @@ -116,6 +118,11 @@ public class PanelBar extends FrameLayout { pv.setExpandedFraction(1f-frac); } } + if (pv.getExpandedHeight() > 0f) { + if (!visible) pv.setVisibility(View.VISIBLE); + } else { + if (visible) pv.setVisibility(View.GONE); + } } if (fullyOpenedPanel != null && !mTracking) { go(STATE_OPEN); @@ -138,6 +145,7 @@ public class PanelBar extends FrameLayout { } else { pv.setExpandedFraction(0); // just in case } + pv.setVisibility(View.GONE); } if (!waiting) { // it's possible that nothing animated, so we replicate the termination diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index 57528a5e95b3b..45a107d8cc35b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -37,6 +37,8 @@ public class PanelView extends FrameLayout { private float mExpandMinDisplayFraction; // classic value: 0.5 (drag open halfway to expand) private float mFlingGestureMaxXVelocityPx; // classic value: 150px/s + private float mFlingGestureMinDistPx; + private float mExpandAccelPx; // classic value: 2000px/s/s private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up") @@ -78,6 +80,8 @@ public class PanelView extends FrameLayout { private float mVel, mAccel; private int mFullHeight = 0; private String mViewName; + protected float mInitialTouchY; + protected float mFinalTouchY; private void animationTick(long dtms) { if (!mTimeAnimator.isStarted()) { @@ -88,7 +92,14 @@ public class PanelView extends FrameLayout { mTimeAnimator.start(); mRubberbanding = STRETCH_PAST_CONTENTS && mExpandedHeight > getFullHeight(); - mClosing = (mExpandedHeight > 0 && mVel < 0) || mRubberbanding; + if (mRubberbanding) { + mClosing = true; + } else if (mVel == 0) { + // if the panel is less than halfway open, close it + mClosing = (mFinalTouchY / getFullHeight()) < 0.5f; + } else { + mClosing = mExpandedHeight > 0 && mVel < 0; + } } else if (dtms > 0) { final float dt = dtms * 0.001f; // ms -> s LOG("tick: v=%.2fpx/s dt=%.4fs", mVel, dt); @@ -159,6 +170,8 @@ public class PanelView extends FrameLayout { mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity); mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity); + mFlingGestureMinDistPx = res.getDimension(R.dimen.fling_gesture_min_dist); + mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1); mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1); @@ -207,6 +220,7 @@ public class PanelView extends FrameLayout { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mTracking = true; + mInitialTouchY = y; mVelocityTracker = VelocityTracker.obtain(); trackMovement(event); mBar.onTrackingStarted(PanelView.this); @@ -223,6 +237,7 @@ public class PanelView extends FrameLayout { case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: + mFinalTouchY = y; mTracking = false; mBar.onTrackingStopped(PanelView.this); trackMovement(event); @@ -243,11 +258,21 @@ public class PanelView extends FrameLayout { if (vel > mFlingGestureMaxOutputVelocityPx) { vel = mFlingGestureMaxOutputVelocityPx; } + + // if you've barely moved your finger, we treat the velocity as 0 + // preventing spurious flings due to touch screen jitter + final float deltaY = (float)Math.abs(mFinalTouchY - mInitialTouchY); + if (deltaY < mFlingGestureMinDistPx + || vel < mFlingGestureMinDistPx) { + vel = 0; + } + if (negative) { vel = -vel; } - LOG("gesture: vraw=(%f,%f) vnorm=(%f,%f) vlinear=%f", + LOG("gesture: dy=%f vraw=(%f,%f) vnorm=(%f,%f) vlinear=%f", + deltaY, mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity(), xVel, yVel, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 7e44b16a84ac6..2f30a3879fdb7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -153,11 +153,18 @@ public class PhoneStatusBar extends BaseStatusBar { int mPixelFormat; Object mQueueLock = new Object(); - // icons - LinearLayout mIcons; - IconMerger mNotificationIcons; - View mMoreIcon; + // viewgroup containing the normal contents of the statusbar + LinearLayout mStatusBarContents; + + // right-hand icons + LinearLayout mSystemIconArea; + + // left-hand icons LinearLayout mStatusIcons; + // the icons themselves + IconMerger mNotificationIcons; + // [+> + View mMoreIcon; // expanded notifications PanelView mNotificationPanel; // the sliding/resizing panel within the notification window @@ -226,8 +233,8 @@ public class PhoneStatusBar extends BaseStatusBar { int[] mAbsPos = new int[2]; Runnable mPostCollapseCleanup = null; - private AnimatorSet mLightsOutAnimation; - private AnimatorSet mLightsOnAnimation; + private Animator mLightsOutAnimation; + private Animator mLightsOnAnimation; // for disabling the status bar int mDisabled = 0; @@ -245,9 +252,9 @@ public class PhoneStatusBar extends BaseStatusBar { @Override public void onAnimationEnd(Animator animation) { // double-check to avoid races - if (mIcons.getAlpha() == 0) { + if (mStatusBarContents.getAlpha() == 0) { Slog.d(TAG, "makeIconsInvisible"); - mIcons.setVisibility(View.INVISIBLE); + mStatusBarContents.setVisibility(View.INVISIBLE); } } }; @@ -307,8 +314,7 @@ public class PhoneStatusBar extends BaseStatusBar { mNotificationPanelIsFullScreenWidth = (mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT); mNotificationPanel.setSystemUiVisibility( - View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER - | (mNotificationPanelIsFullScreenWidth ? 0 : View.STATUS_BAR_DISABLE_SYSTEM_INFO)); + View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER | View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS); if (!ActivityManager.isHighEndGfx()) { mStatusBarWindow.setBackground(null); @@ -343,10 +349,12 @@ public class PhoneStatusBar extends BaseStatusBar { // figure out which pixel-format to use for the status bar. mPixelFormat = PixelFormat.OPAQUE; + + mSystemIconArea = (LinearLayout) mStatusBarView.findViewById(R.id.system_icon_area); mStatusIcons = (LinearLayout)mStatusBarView.findViewById(R.id.statusIcons); mNotificationIcons = (IconMerger)mStatusBarView.findViewById(R.id.notificationIcons); mNotificationIcons.setOverflowIndicator(mMoreIcon); - mIcons = (LinearLayout)mStatusBarView.findViewById(R.id.icons); + mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents); mTickerView = mStatusBarView.findViewById(R.id.ticker); mPile = (NotificationRowLayout)mStatusBarWindow.findViewById(R.id.latestItems); @@ -431,6 +439,8 @@ public class PhoneStatusBar extends BaseStatusBar { mSettingsPanel.setService(this); mSettingsPanel.setup(mNetworkController, mBluetoothController, mBatteryController, mLocationController); + mSettingsPanel.setSystemUiVisibility( + View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER | View.STATUS_BAR_DISABLE_SYSTEM_INFO); if (!ActivityManager.isHighEndGfx()) { mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor( @@ -1016,22 +1026,18 @@ public class PhoneStatusBar extends BaseStatusBar { Slog.d(TAG, flagdbg.toString()); if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) { - mIcons.animate().cancel(); + mSystemIconArea.animate().cancel(); if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) { - if (mTicking) { - mTicker.halt(); - } - mIcons.animate() + mSystemIconArea.animate() .alpha(0f) .translationY(mNaturalBarHeight*0.5f) - //.setStartDelay(100) .setDuration(175) .setInterpolator(new DecelerateInterpolator(1.5f)) .setListener(mMakeIconsInvisible) .start(); } else { - mIcons.setVisibility(View.VISIBLE); - mIcons.animate() + mSystemIconArea.setVisibility(View.VISIBLE); + mSystemIconArea.animate() .alpha(1f) .translationY(0) .setStartDelay(0) @@ -1068,13 +1074,24 @@ public class PhoneStatusBar extends BaseStatusBar { if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { if (mTicking) { mTicker.halt(); - } else { - setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out); } + + mNotificationIcons.animate() + .alpha(0f) + .translationY(mNaturalBarHeight*0.5f) + .setDuration(175) + .setInterpolator(new DecelerateInterpolator(1.5f)) + .setListener(mMakeIconsInvisible) + .start(); } else { - if (!mExpandedVisible) { - setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); - } + mNotificationIcons.setVisibility(View.VISIBLE); + mNotificationIcons.animate() + .alpha(1f) + .translationY(0) + .setStartDelay(0) + .setInterpolator(new DecelerateInterpolator(1.5f)) + .setDuration(175) + .start(); } } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { @@ -1340,30 +1357,11 @@ public class PhoneStatusBar extends BaseStatusBar { private void setStatusBarLowProfile(boolean lightsOut) { if (mLightsOutAnimation == null) { - final View notifications = mStatusBarView.findViewById(R.id.notification_icon_area); - final View systemIcons = mStatusBarView.findViewById(R.id.statusIcons); - final View signal = mStatusBarView.findViewById(R.id.signal_cluster); - final View battery = mStatusBarView.findViewById(R.id.battery); - final View clock = mStatusBarView.findViewById(R.id.clock); - - mLightsOutAnimation = new AnimatorSet(); - mLightsOutAnimation.playTogether( - ObjectAnimator.ofFloat(notifications, View.ALPHA, 0), - ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 0), - ObjectAnimator.ofFloat(signal, View.ALPHA, 0), - ObjectAnimator.ofFloat(battery, View.ALPHA, 0.5f), - ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f) - ); + mLightsOutAnimation = ObjectAnimator.ofFloat(mStatusBarContents, View.ALPHA, 0); mLightsOutAnimation.setDuration(750); mLightsOnAnimation = new AnimatorSet(); - mLightsOnAnimation.playTogether( - ObjectAnimator.ofFloat(notifications, View.ALPHA, 1), - ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 1), - ObjectAnimator.ofFloat(signal, View.ALPHA, 1), - ObjectAnimator.ofFloat(battery, View.ALPHA, 1), - ObjectAnimator.ofFloat(clock, View.ALPHA, 1) - ); + mLightsOnAnimation = ObjectAnimator.ofFloat(mStatusBarContents, View.ALPHA, 1); mLightsOnAnimation.setDuration(250); } @@ -1453,25 +1451,25 @@ public class PhoneStatusBar extends BaseStatusBar { @Override public void tickerStarting() { mTicking = true; - mIcons.setVisibility(View.GONE); + mStatusBarContents.setVisibility(View.GONE); mTickerView.setVisibility(View.VISIBLE); mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null)); - mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null)); + mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null)); } @Override public void tickerDone() { - mIcons.setVisibility(View.VISIBLE); + mStatusBarContents.setVisibility(View.VISIBLE); mTickerView.setVisibility(View.GONE); - mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null)); + mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null)); mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out, mTickingDoneListener)); } public void tickerHalting() { - mIcons.setVisibility(View.VISIBLE); + mStatusBarContents.setVisibility(View.VISIBLE); mTickerView.setVisibility(View.GONE); - mIcons.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null)); + mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null)); mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.fade_out, mTickingDoneListener)); } @@ -1649,40 +1647,6 @@ public class PhoneStatusBar extends BaseStatusBar { String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels)); } - void performDisableActions(int net) { - int old = mDisabled; - int diff = net ^ old; - mDisabled = net; - - // act accordingly - if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) { - if ((net & StatusBarManager.DISABLE_EXPAND) != 0) { - Slog.d(TAG, "DISABLE_EXPAND: yes"); - animateCollapse(); - } - } - if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { - if ((net & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { - Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes"); - if (mTicking) { - mNotificationIcons.setVisibility(View.INVISIBLE); - mTicker.halt(); - } else { - setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out); - } - } else { - Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no"); - if (!mExpandedVisible) { - setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); - } - } - } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { - if (mTicking && (net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { - mTicker.halt(); - } - } - } - private View.OnClickListener mClearButtonListener = new View.OnClickListener() { public void onClick(View v) { synchronized (mNotificationData) {