Loading packages/SystemUI/res/values/dimens.xml +3 −0 Original line number Diff line number Diff line Loading @@ -272,6 +272,9 @@ <!-- The padding between the individual notification cards. --> <dimen name="notification_padding">4dp</dimen> <!-- The minimum amount of top overscroll to go to the quick settings. --> <dimen name="min_top_overscroll_to_qs">36dp</dimen> <!-- The height of the collapsed speed bump view. --> <dimen name="speed_bump_height_collapsed">24dp</dimen> Loading packages/SystemUI/src/com/android/systemui/ExpandHelper.java +118 −69 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ public class ExpandHelper implements Gefingerpoken { boolean canChildBeExpanded(View v); void setUserExpandedChild(View v, boolean userExpanded); void setUserLockedChild(View v, boolean userLocked); void expansionStateChanged(boolean isExpanding); } private static final String TAG = "ExpandHelper"; Loading Loading @@ -77,7 +78,6 @@ public class ExpandHelper implements Gefingerpoken { private boolean mWatchingForPull; private boolean mHasPopped; private View mEventSource; private View mCurrView; private float mOldHeight; private float mNaturalHeight; private float mInitialTouchFocusY; Loading @@ -86,8 +86,7 @@ public class ExpandHelper implements Gefingerpoken { private float mLastFocusY; private float mLastSpanY; private int mTouchSlop; private int mLastMotionY; private float mPopLimit; private float mLastMotionY; private int mPopDuration; private float mPullGestureMinXSpan; private Callback mCallback; Loading @@ -95,10 +94,14 @@ public class ExpandHelper implements Gefingerpoken { private ViewScaler mScaler; private ObjectAnimator mScaleAnimation; private Vibrator mVibrator; private boolean mEnabled = true; private ExpandableView mResizedView; private float mCurrentHeight; private int mSmallSize; private int mLargeSize; private float mMaximumStretch; private boolean mOnlyMovements; private int mGravity; Loading @@ -109,17 +112,14 @@ public class ExpandHelper implements Gefingerpoken { @Override public boolean onScaleBegin(ScaleGestureDetector detector) { if (DEBUG_SCALE) Log.v(TAG, "onscalebegin()"); float focusX = detector.getFocusX(); float focusY = detector.getFocusY(); final ExpandableView underFocus = findView(focusX, focusY); startExpanding(underFocus, STRETCH); startExpanding(mResizedView, STRETCH); return mExpanding; } @Override public boolean onScale(ScaleGestureDetector detector) { if (DEBUG_SCALE) Log.v(TAG, "onscale() on " + mCurrView); if (DEBUG_SCALE) Log.v(TAG, "onscale() on " + mResizedView); return true; } Loading @@ -138,6 +138,7 @@ public class ExpandHelper implements Gefingerpoken { public void setHeight(float h) { if (DEBUG_SCALE) Log.v(TAG, "SetHeight: setting to " + h); mView.setActualHeight((int) h); mCurrentHeight = h; } public float getHeight() { return mView.getActualHeight(); Loading Loading @@ -165,7 +166,6 @@ public class ExpandHelper implements Gefingerpoken { mGravity = Gravity.TOP; mScaleAnimation = ObjectAnimator.ofFloat(mScaler, "height", 0f); mScaleAnimation.setDuration(EXPAND_DURATION); mPopLimit = mContext.getResources().getDimension(R.dimen.blinds_pop_threshold); mPopDuration = mContext.getResources().getInteger(R.integer.blinds_pop_duration_ms); mPullGestureMinXSpan = mContext.getResources().getDimension(R.dimen.pull_span_min); Loading @@ -188,7 +188,6 @@ public class ExpandHelper implements Gefingerpoken { float target = hand + mOldHeight; float newHeight = clamp(target); mScaler.setHeight(newHeight); mLastFocusY = mSGD.getFocusY(); mLastSpanY = mSGD.getCurrentSpan(); } Loading Loading @@ -252,6 +251,9 @@ public class ExpandHelper implements Gefingerpoken { @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (!isEnabled()) { return false; } final int action = ev.getAction(); if (DEBUG_SCALE) Log.d(TAG, "intercept: act=" + MotionEvent.actionToString(action) + " expanding=" + mExpanding + Loading @@ -270,48 +272,46 @@ public class ExpandHelper implements Gefingerpoken { if (DEBUG_SCALE) Log.d(TAG, "set initial span: " + mInitialTouchSpan); if (mExpanding) { mLastMotionY = ev.getRawY(); return true; } else { if ((action == MotionEvent.ACTION_MOVE) && 0 != (mExpansionStyle & BLINDS)) { // we've begun Venetian blinds style expansion return true; } switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_MOVE: { final float xspan = mSGD.getCurrentSpanX(); if ((action == MotionEvent.ACTION_MOVE && xspan > mPullGestureMinXSpan && xspan > mSGD.getCurrentSpanY())) { if (xspan > mPullGestureMinXSpan && xspan > mSGD.getCurrentSpanY() && !mExpanding) { // detect a vertical pulling gesture with fingers somewhat separated if (DEBUG_SCALE) Log.v(TAG, "got pull gesture (xspan=" + xspan + "px)"); final ExpandableView underFocus = findView(x, y); startExpanding(underFocus, PULL); return true; startExpanding(mResizedView, PULL); mWatchingForPull = false; } if (mScrollAdapter != null && !mScrollAdapter.isScrolledToTop()) { return false; } // Now look for other gestures switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_MOVE: { if (mWatchingForPull) { final int yDiff = y - mLastMotionY; final float yDiff = ev.getRawY() - mInitialTouchY; if (yDiff > mTouchSlop) { if (DEBUG) Log.v(TAG, "got venetian gesture (dy=" + yDiff + "px)"); mLastMotionY = y; final ExpandableView underFocus = findView(x, y); if (startExpanding(underFocus, BLINDS)) { mInitialTouchY = mLastMotionY; mWatchingForPull = false; if (mResizedView != null && !isFullyExpanded(mResizedView)) { if (startExpanding(mResizedView, BLINDS)) { mLastMotionY = ev.getRawY(); mInitialTouchY = ev.getRawY(); mHasPopped = false; } } } } break; } case MotionEvent.ACTION_DOWN: mWatchingForPull = mScrollAdapter != null && isInside(mScrollAdapter.getHostView(), x, y); mLastMotionY = y; isInside(mScrollAdapter.getHostView(), x, y) && mScrollAdapter.isScrolledToTop(); mResizedView = findView(x, y); mInitialTouchY = ev.getY(); break; case MotionEvent.ACTION_CANCEL: Loading @@ -321,12 +321,28 @@ public class ExpandHelper implements Gefingerpoken { clearView(); break; } mLastMotionY = ev.getRawY(); return mExpanding; } } public void setEnabled(boolean enable) { mEnabled = enable; } private boolean isEnabled() { return mEnabled; } private boolean isFullyExpanded(ExpandableView underFocus) { return underFocus.getIntrinsicHeight() == underFocus.getMaxHeight(); } @Override public boolean onTouchEvent(MotionEvent ev) { if (!isEnabled()) { return false; } final int action = ev.getActionMasked(); if (DEBUG_SCALE) Log.d(TAG, "touch: act=" + MotionEvent.actionToString(action) + " expanding=" + mExpanding + Loading @@ -335,47 +351,71 @@ public class ExpandHelper implements Gefingerpoken { (0 != (mExpansionStyle & STRETCH) ? " (stretch)" : "")); mSGD.onTouchEvent(ev); final int x = (int) mSGD.getFocusX(); final int y = (int) mSGD.getFocusY(); if (mOnlyMovements) { mLastMotionY = ev.getRawY(); return false; } switch (action) { case MotionEvent.ACTION_DOWN: mWatchingForPull = mScrollAdapter != null && isInside(mScrollAdapter.getHostView(), x, y); mResizedView = findView(x, y); mInitialTouchY = ev.getY(); break; case MotionEvent.ACTION_MOVE: { if (0 != (mExpansionStyle & BLINDS)) { final float rawHeight = ev.getY() - mInitialTouchY + mOldHeight; if (mWatchingForPull) { final float yDiff = ev.getRawY() - mInitialTouchY; if (yDiff > mTouchSlop) { if (DEBUG) Log.v(TAG, "got venetian gesture (dy=" + yDiff + "px)"); mWatchingForPull = false; if (mResizedView != null && !isFullyExpanded(mResizedView)) { if (startExpanding(mResizedView, BLINDS)) { mInitialTouchY = ev.getRawY(); mLastMotionY = ev.getRawY(); mHasPopped = false; } } } } if (mExpanding && 0 != (mExpansionStyle & BLINDS)) { final float rawHeight = ev.getRawY() - mLastMotionY + mCurrentHeight; final float newHeight = clamp(rawHeight); final boolean wasClosed = (mOldHeight == mSmallSize); boolean isFinished = false; boolean expanded = false; if (rawHeight > mNaturalHeight) { isFinished = true; expanded = true; } if (rawHeight < mSmallSize) { isFinished = true; expanded = false; } final float pull = Math.abs(ev.getY() - mInitialTouchY); if (mHasPopped || pull > mPopLimit) { if (!mHasPopped) { vibrate(mPopDuration); mHasPopped = true; } } if (mHasPopped) { mScaler.setHeight(newHeight); } final int x = (int) mSGD.getFocusX(); final int y = (int) mSGD.getFocusY(); ExpandableView underFocus = findView(x, y); if (isFinished && underFocus != null && underFocus != mCurrView) { finishExpanding(false); // @@@ needed? startExpanding(underFocus, BLINDS); mInitialTouchY = y; mHasPopped = false; mLastMotionY = ev.getRawY(); if (isFinished) { mCallback.setUserExpandedChild(mResizedView, expanded); mCallback.expansionStateChanged(false); return false; } else { mCallback.expansionStateChanged(true); } return true; } if (mExpanding) { // Gestural expansion is running updateExpansion(); mLastMotionY = ev.getRawY(); return true; } Loading @@ -396,6 +436,7 @@ public class ExpandHelper implements Gefingerpoken { clearView(); break; } mLastMotionY = ev.getRawY(); return true; } Loading @@ -407,15 +448,16 @@ public class ExpandHelper implements Gefingerpoken { return false; } mExpansionStyle = expandType; if (mExpanding && v == mCurrView) { if (mExpanding && v == mResizedView) { return true; } mExpanding = true; mCallback.expansionStateChanged(true); if (DEBUG) Log.d(TAG, "scale type " + expandType + " beginning on view: " + v); mCallback.setUserLockedChild(v, true); setView(v); mScaler.setView((ExpandableView) v); mScaler.setView(v); mOldHeight = mScaler.getHeight(); mCurrentHeight = mOldHeight; if (mCallback.canChildBeExpanded(v)) { if (DEBUG) Log.d(TAG, "working on an expandable child"); mNaturalHeight = mScaler.getNaturalHeight(mLargeSize); Loading @@ -425,14 +467,13 @@ public class ExpandHelper implements Gefingerpoken { } if (DEBUG) Log.d(TAG, "got mOldHeight: " + mOldHeight + " mNaturalHeight: " + mNaturalHeight); v.getParent().requestDisallowInterceptTouchEvent(true); return true; } private void finishExpanding(boolean force) { if (!mExpanding) return; if (DEBUG) Log.d(TAG, "scale in finishing on view: " + mCurrView); if (DEBUG) Log.d(TAG, "scale in finishing on view: " + mResizedView); float currentHeight = mScaler.getHeight(); float targetHeight = mSmallSize; Loading @@ -446,11 +487,12 @@ public class ExpandHelper implements Gefingerpoken { if (mScaleAnimation.isRunning()) { mScaleAnimation.cancel(); } mCallback.setUserExpandedChild(mCurrView, targetHeight == mNaturalHeight); mCallback.setUserExpandedChild(mResizedView, targetHeight == mNaturalHeight); mCallback.expansionStateChanged(false); if (targetHeight != currentHeight) { mScaleAnimation.setFloatValues(targetHeight); mScaleAnimation.setupStartValues(); final View scaledView = mCurrView; final View scaledView = mResizedView; mScaleAnimation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { Loading @@ -460,7 +502,7 @@ public class ExpandHelper implements Gefingerpoken { }); mScaleAnimation.start(); } else { mCallback.setUserLockedChild(mCurrView, false); mCallback.setUserLockedChild(mResizedView, false); } mExpanding = false; Loading @@ -470,16 +512,11 @@ public class ExpandHelper implements Gefingerpoken { if (DEBUG) Log.d(TAG, "currentHeight is: " + currentHeight); if (DEBUG) Log.d(TAG, "mSmallSize is: " + mSmallSize); if (DEBUG) Log.d(TAG, "targetHeight is: " + targetHeight); if (DEBUG) Log.d(TAG, "scale was finished on view: " + mCurrView); if (DEBUG) Log.d(TAG, "scale was finished on view: " + mResizedView); } private void clearView() { mCurrView = null; } private void setView(View v) { mCurrView = v; mResizedView = null; } /** Loading @@ -493,6 +530,18 @@ public class ExpandHelper implements Gefingerpoken { mSGD = new ScaleGestureDetector(mContext, mScaleGestureListener); } /** * Change the expansion mode to only observe movements and don't perform any resizing. * This is needed when the expanding is finished and the scroller kicks in, * performing an overscroll motion. We only want to shrink it again when we are not * overscrolled. * * @param onlyMovements Should only movements be observed? */ public void onlyObserveMovements(boolean onlyMovements) { mOnlyMovements = onlyMovements; } /** * Triggers haptic feedback. */ Loading packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java +2 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import android.view.View; import android.view.ViewConfiguration; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import com.android.systemui.ExpandHelper; import com.android.systemui.Gefingerpoken; import com.android.systemui.R; Loading Loading @@ -87,6 +86,7 @@ public class DragDownHelper implements Gefingerpoken { captureStartingChild(mInitialTouchX, mInitialTouchY); mInitialTouchY = y; mInitialTouchX = x; mOnDragDownListener.onTouchSlopExceeded(); return true; } break; Loading Loading @@ -202,5 +202,6 @@ public class DragDownHelper implements Gefingerpoken { void onDraggedDown(View startingChild); void onDragDownReset(); void onThresholdReached(); void onTouchSlopExceeded(); } } packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +37 −43 Original line number Diff line number Diff line Loading @@ -83,10 +83,7 @@ public class NotificationPanelView extends PanelView implements private float mQsExpansionHeight; private int mQsMinExpansionHeight; private int mQsMaxExpansionHeight; private int mMinStackHeight; private int mQsPeekHeight; private float mNotificationTranslation; private int mStackScrollerIntrinsicPadding; private boolean mStackScrollerOverscrolling; private boolean mQsExpansionEnabled = true; private ValueAnimator mQsExpansionAnimator; Loading Loading @@ -165,7 +162,6 @@ public class NotificationPanelView extends PanelView implements super.loadDimens(); mNotificationTopPadding = getResources().getDimensionPixelSize( R.dimen.notifications_top_padding); mMinStackHeight = getResources().getDimensionPixelSize(R.dimen.collapsed_stack_height); mFlingAnimationUtils = new FlingAnimationUtils(getContext(), 0.4f); mStatusBarMinHeight = getResources().getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); Loading @@ -185,7 +181,8 @@ public class NotificationPanelView extends PanelView implements mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getHeight(); if (mQsExpanded) { if (mQsFullyExpanded) { setQsStackScrollerPadding(mQsMaxExpansionHeight); mQsExpansionHeight = mQsMaxExpansionHeight; requestScrollerTopPaddingUpdate(false /* animate */); } } else { if (!mStackScrollerOverscrolling) { Loading @@ -202,11 +199,12 @@ public class NotificationPanelView extends PanelView implements */ private void positionClockAndNotifications() { boolean animateClock = mNotificationStackScroller.isAddOrRemoveAnimationPending(); int stackScrollerPadding; if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) { int bottom = mStackScrollerOverscrolling ? mHeader.getCollapsedHeight() : mHeader.getBottom(); mStackScrollerIntrinsicPadding = bottom + mQsPeekHeight stackScrollerPadding = bottom + mQsPeekHeight + mNotificationTopPadding; mTopPaddingAdjustment = 0; } else { Loading @@ -224,11 +222,11 @@ public class NotificationPanelView extends PanelView implements mKeyguardStatusView.setY(mClockPositionResult.clockY); } applyClockAlpha(mClockPositionResult.clockAlpha); mStackScrollerIntrinsicPadding = mClockPositionResult.stackScrollerPadding; stackScrollerPadding = mClockPositionResult.stackScrollerPadding; mTopPaddingAdjustment = mClockPositionResult.stackScrollerPaddingAdjustment; } mNotificationStackScroller.setTopPadding(mStackScrollerIntrinsicPadding, mAnimateNextTopPaddingChange || animateClock); mNotificationStackScroller.setIntrinsicPadding(stackScrollerPadding); requestScrollerTopPaddingUpdate(animateClock); mAnimateNextTopPaddingChange = false; } Loading Loading @@ -384,6 +382,7 @@ public class NotificationPanelView extends PanelView implements mInitialTouchX = x; mQsTracking = true; mIntercepting = false; mNotificationStackScroller.removeLongPressCallback(); return true; } break; Loading Loading @@ -523,6 +522,13 @@ public class NotificationPanelView extends PanelView implements updateQsState(); } @Override public void flingTopOverscroll(float velocity, boolean open) { mStackScrollerOverscrolling = false; setQsExpansion(mQsExpansionHeight); flingSettings(velocity, open); } private void onQsExpansionStarted() { onQsExpansionStarted(0); } Loading Loading @@ -554,7 +560,9 @@ public class NotificationPanelView extends PanelView implements mHeader.setExpanded(expandVisually, mStackScrollerOverscrolling); mNotificationStackScroller.setEnabled(!mQsExpanded); mQsPanel.setVisibility(expandVisually ? View.VISIBLE : View.INVISIBLE); mQsContainer.setVisibility(mKeyguardShowing && !mQsExpanded ? View.INVISIBLE : View.VISIBLE); mQsContainer.setVisibility(mKeyguardShowing && !expandVisually ? View.INVISIBLE : View.VISIBLE); mScrollView.setTouchEnabled(mQsExpanded); } Loading @@ -569,9 +577,7 @@ public class NotificationPanelView extends PanelView implements mQsExpansionHeight = height; mHeader.setExpansion(height - mQsPeekHeight); setQsTranslation(height); if (!mStackScrollerOverscrolling) { setQsStackScrollerPadding(height); } requestScrollerTopPaddingUpdate(false /* animate */); mStatusBar.userActivity(); } Loading @@ -579,24 +585,11 @@ public class NotificationPanelView extends PanelView implements mQsContainer.setY(height - mQsContainer.getHeight()); } private void setQsStackScrollerPadding(float height) { float start = height - mScrollView.getScrollY() + mNotificationTopPadding; float stackHeight = mNotificationStackScroller.getHeight() - start; if (stackHeight <= mMinStackHeight) { float overflow = mMinStackHeight - stackHeight; stackHeight = mMinStackHeight; start = mNotificationStackScroller.getHeight() - stackHeight; mNotificationStackScroller.setTranslationY(overflow); mNotificationTranslation = overflow + mScrollView.getScrollY(); } else { mNotificationStackScroller.setTranslationY(0); mNotificationTranslation = mScrollView.getScrollY(); } mNotificationStackScroller.setTopPadding(clampQsStackScrollerPadding((int) start), false); } private int clampQsStackScrollerPadding(int desiredPadding) { return Math.max(desiredPadding, mStackScrollerIntrinsicPadding); private void requestScrollerTopPaddingUpdate(boolean animate) { mNotificationStackScroller.updateTopPadding(mQsExpansionHeight, mScrollView.getScrollY(), mAnimateNextTopPaddingChange || animate); } private void trackMovement(MotionEvent event) { Loading Loading @@ -705,9 +698,11 @@ public class NotificationPanelView extends PanelView implements protected int getMaxPanelHeight() { // TODO: Figure out transition for collapsing when QS is open, adjust height here. int maxPanelHeight = super.getMaxPanelHeight(); int emptyBottomMargin = mStackScrollerContainer.getHeight() - mNotificationStackScroller.getHeight() + mNotificationStackScroller.getEmptyBottomMargin(); int emptyBottomMargin = mNotificationStackScroller.getEmptyBottomMargin(); emptyBottomMargin = (int) Math.max(0, emptyBottomMargin - mNotificationStackScroller.getCurrentOverScrollAmount(true)); emptyBottomMargin += mStackScrollerContainer.getHeight() - mNotificationStackScroller.getHeight(); int maxHeight = maxPanelHeight - emptyBottomMargin - mTopPaddingAdjustment; maxHeight = Math.max(maxHeight, mStatusBarMinHeight); return maxHeight; Loading Loading @@ -814,13 +809,14 @@ public class NotificationPanelView extends PanelView implements @Override protected void onOverExpansionChanged(float overExpansion) { if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) { float currentOverScroll = mNotificationStackScroller.getCurrentOverScrolledPixels(true); float expansionChange = overExpansion - mOverExpansion; expansionChange *= EXPANSION_RUBBER_BAND_EXTRA_FACTOR; mNotificationStackScroller.setOverScrolledPixels(currentOverScroll + expansionChange, true /* onTop */, false /* animate */); super.onOverExpansionChanged(overExpansion); } } @Override Loading @@ -835,7 +831,6 @@ public class NotificationPanelView extends PanelView implements @Override protected void onTrackingStopped(boolean expand) { super.onTrackingStopped(expand); mOverExpansion = 0.0f; mNotificationStackScroller.setOverScrolledPixels(0.0f, true /* onTop */, true /* animate */); if (expand && (mStatusBar.getBarState() == StatusBarState.KEYGUARD || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED)) { Loading @@ -860,8 +855,7 @@ public class NotificationPanelView extends PanelView implements @Override public void onScrollChanged() { if (mQsExpanded) { mNotificationStackScroller.setTranslationY( mNotificationTranslation - mScrollView.getScrollY()); requestScrollerTopPaddingUpdate(false /* animate */); } } Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +6 −5 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ public abstract class PanelView extends FrameLayout { private int mEdgeTapAreaWidth; private float mInitialOffsetOnTouch; private float mExpandedFraction = 0; private float mExpandedHeight = 0; protected float mExpandedHeight = 0; private boolean mJustPeeked; private boolean mClosing; protected boolean mTracking; Loading Loading @@ -369,8 +369,10 @@ public abstract class PanelView extends FrameLayout { protected void fling(float vel, boolean expand) { cancelPeek(); float target = expand ? getMaxPanelHeight() : 0.0f; if (target == mExpandedHeight) { if (target == mExpandedHeight || mOverExpansion > 0) { onExpandingFinished(); mExpandedHeight = target; mOverExpansion = 0.0f; mBar.panelExpansionChanged(this, mExpandedFraction); return; } Loading Loading @@ -459,6 +461,7 @@ public abstract class PanelView extends FrameLayout { overExpansion = Math.max(0, overExpansion); if (overExpansion != mOverExpansion) { onOverExpansionChanged(overExpansion); mOverExpansion = overExpansion; } if (DEBUG) { Loading @@ -469,9 +472,7 @@ public abstract class PanelView extends FrameLayout { mExpandedFraction = Math.min(1f, (fh == 0) ? 0 : mExpandedHeight / fh); } protected void onOverExpansionChanged(float overExpansion) { mOverExpansion = overExpansion; } protected abstract void onOverExpansionChanged(float overExpansion); protected abstract void onHeightUpdated(float expandedHeight); Loading Loading
packages/SystemUI/res/values/dimens.xml +3 −0 Original line number Diff line number Diff line Loading @@ -272,6 +272,9 @@ <!-- The padding between the individual notification cards. --> <dimen name="notification_padding">4dp</dimen> <!-- The minimum amount of top overscroll to go to the quick settings. --> <dimen name="min_top_overscroll_to_qs">36dp</dimen> <!-- The height of the collapsed speed bump view. --> <dimen name="speed_bump_height_collapsed">24dp</dimen> Loading
packages/SystemUI/src/com/android/systemui/ExpandHelper.java +118 −69 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ public class ExpandHelper implements Gefingerpoken { boolean canChildBeExpanded(View v); void setUserExpandedChild(View v, boolean userExpanded); void setUserLockedChild(View v, boolean userLocked); void expansionStateChanged(boolean isExpanding); } private static final String TAG = "ExpandHelper"; Loading Loading @@ -77,7 +78,6 @@ public class ExpandHelper implements Gefingerpoken { private boolean mWatchingForPull; private boolean mHasPopped; private View mEventSource; private View mCurrView; private float mOldHeight; private float mNaturalHeight; private float mInitialTouchFocusY; Loading @@ -86,8 +86,7 @@ public class ExpandHelper implements Gefingerpoken { private float mLastFocusY; private float mLastSpanY; private int mTouchSlop; private int mLastMotionY; private float mPopLimit; private float mLastMotionY; private int mPopDuration; private float mPullGestureMinXSpan; private Callback mCallback; Loading @@ -95,10 +94,14 @@ public class ExpandHelper implements Gefingerpoken { private ViewScaler mScaler; private ObjectAnimator mScaleAnimation; private Vibrator mVibrator; private boolean mEnabled = true; private ExpandableView mResizedView; private float mCurrentHeight; private int mSmallSize; private int mLargeSize; private float mMaximumStretch; private boolean mOnlyMovements; private int mGravity; Loading @@ -109,17 +112,14 @@ public class ExpandHelper implements Gefingerpoken { @Override public boolean onScaleBegin(ScaleGestureDetector detector) { if (DEBUG_SCALE) Log.v(TAG, "onscalebegin()"); float focusX = detector.getFocusX(); float focusY = detector.getFocusY(); final ExpandableView underFocus = findView(focusX, focusY); startExpanding(underFocus, STRETCH); startExpanding(mResizedView, STRETCH); return mExpanding; } @Override public boolean onScale(ScaleGestureDetector detector) { if (DEBUG_SCALE) Log.v(TAG, "onscale() on " + mCurrView); if (DEBUG_SCALE) Log.v(TAG, "onscale() on " + mResizedView); return true; } Loading @@ -138,6 +138,7 @@ public class ExpandHelper implements Gefingerpoken { public void setHeight(float h) { if (DEBUG_SCALE) Log.v(TAG, "SetHeight: setting to " + h); mView.setActualHeight((int) h); mCurrentHeight = h; } public float getHeight() { return mView.getActualHeight(); Loading Loading @@ -165,7 +166,6 @@ public class ExpandHelper implements Gefingerpoken { mGravity = Gravity.TOP; mScaleAnimation = ObjectAnimator.ofFloat(mScaler, "height", 0f); mScaleAnimation.setDuration(EXPAND_DURATION); mPopLimit = mContext.getResources().getDimension(R.dimen.blinds_pop_threshold); mPopDuration = mContext.getResources().getInteger(R.integer.blinds_pop_duration_ms); mPullGestureMinXSpan = mContext.getResources().getDimension(R.dimen.pull_span_min); Loading @@ -188,7 +188,6 @@ public class ExpandHelper implements Gefingerpoken { float target = hand + mOldHeight; float newHeight = clamp(target); mScaler.setHeight(newHeight); mLastFocusY = mSGD.getFocusY(); mLastSpanY = mSGD.getCurrentSpan(); } Loading Loading @@ -252,6 +251,9 @@ public class ExpandHelper implements Gefingerpoken { @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (!isEnabled()) { return false; } final int action = ev.getAction(); if (DEBUG_SCALE) Log.d(TAG, "intercept: act=" + MotionEvent.actionToString(action) + " expanding=" + mExpanding + Loading @@ -270,48 +272,46 @@ public class ExpandHelper implements Gefingerpoken { if (DEBUG_SCALE) Log.d(TAG, "set initial span: " + mInitialTouchSpan); if (mExpanding) { mLastMotionY = ev.getRawY(); return true; } else { if ((action == MotionEvent.ACTION_MOVE) && 0 != (mExpansionStyle & BLINDS)) { // we've begun Venetian blinds style expansion return true; } switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_MOVE: { final float xspan = mSGD.getCurrentSpanX(); if ((action == MotionEvent.ACTION_MOVE && xspan > mPullGestureMinXSpan && xspan > mSGD.getCurrentSpanY())) { if (xspan > mPullGestureMinXSpan && xspan > mSGD.getCurrentSpanY() && !mExpanding) { // detect a vertical pulling gesture with fingers somewhat separated if (DEBUG_SCALE) Log.v(TAG, "got pull gesture (xspan=" + xspan + "px)"); final ExpandableView underFocus = findView(x, y); startExpanding(underFocus, PULL); return true; startExpanding(mResizedView, PULL); mWatchingForPull = false; } if (mScrollAdapter != null && !mScrollAdapter.isScrolledToTop()) { return false; } // Now look for other gestures switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_MOVE: { if (mWatchingForPull) { final int yDiff = y - mLastMotionY; final float yDiff = ev.getRawY() - mInitialTouchY; if (yDiff > mTouchSlop) { if (DEBUG) Log.v(TAG, "got venetian gesture (dy=" + yDiff + "px)"); mLastMotionY = y; final ExpandableView underFocus = findView(x, y); if (startExpanding(underFocus, BLINDS)) { mInitialTouchY = mLastMotionY; mWatchingForPull = false; if (mResizedView != null && !isFullyExpanded(mResizedView)) { if (startExpanding(mResizedView, BLINDS)) { mLastMotionY = ev.getRawY(); mInitialTouchY = ev.getRawY(); mHasPopped = false; } } } } break; } case MotionEvent.ACTION_DOWN: mWatchingForPull = mScrollAdapter != null && isInside(mScrollAdapter.getHostView(), x, y); mLastMotionY = y; isInside(mScrollAdapter.getHostView(), x, y) && mScrollAdapter.isScrolledToTop(); mResizedView = findView(x, y); mInitialTouchY = ev.getY(); break; case MotionEvent.ACTION_CANCEL: Loading @@ -321,12 +321,28 @@ public class ExpandHelper implements Gefingerpoken { clearView(); break; } mLastMotionY = ev.getRawY(); return mExpanding; } } public void setEnabled(boolean enable) { mEnabled = enable; } private boolean isEnabled() { return mEnabled; } private boolean isFullyExpanded(ExpandableView underFocus) { return underFocus.getIntrinsicHeight() == underFocus.getMaxHeight(); } @Override public boolean onTouchEvent(MotionEvent ev) { if (!isEnabled()) { return false; } final int action = ev.getActionMasked(); if (DEBUG_SCALE) Log.d(TAG, "touch: act=" + MotionEvent.actionToString(action) + " expanding=" + mExpanding + Loading @@ -335,47 +351,71 @@ public class ExpandHelper implements Gefingerpoken { (0 != (mExpansionStyle & STRETCH) ? " (stretch)" : "")); mSGD.onTouchEvent(ev); final int x = (int) mSGD.getFocusX(); final int y = (int) mSGD.getFocusY(); if (mOnlyMovements) { mLastMotionY = ev.getRawY(); return false; } switch (action) { case MotionEvent.ACTION_DOWN: mWatchingForPull = mScrollAdapter != null && isInside(mScrollAdapter.getHostView(), x, y); mResizedView = findView(x, y); mInitialTouchY = ev.getY(); break; case MotionEvent.ACTION_MOVE: { if (0 != (mExpansionStyle & BLINDS)) { final float rawHeight = ev.getY() - mInitialTouchY + mOldHeight; if (mWatchingForPull) { final float yDiff = ev.getRawY() - mInitialTouchY; if (yDiff > mTouchSlop) { if (DEBUG) Log.v(TAG, "got venetian gesture (dy=" + yDiff + "px)"); mWatchingForPull = false; if (mResizedView != null && !isFullyExpanded(mResizedView)) { if (startExpanding(mResizedView, BLINDS)) { mInitialTouchY = ev.getRawY(); mLastMotionY = ev.getRawY(); mHasPopped = false; } } } } if (mExpanding && 0 != (mExpansionStyle & BLINDS)) { final float rawHeight = ev.getRawY() - mLastMotionY + mCurrentHeight; final float newHeight = clamp(rawHeight); final boolean wasClosed = (mOldHeight == mSmallSize); boolean isFinished = false; boolean expanded = false; if (rawHeight > mNaturalHeight) { isFinished = true; expanded = true; } if (rawHeight < mSmallSize) { isFinished = true; expanded = false; } final float pull = Math.abs(ev.getY() - mInitialTouchY); if (mHasPopped || pull > mPopLimit) { if (!mHasPopped) { vibrate(mPopDuration); mHasPopped = true; } } if (mHasPopped) { mScaler.setHeight(newHeight); } final int x = (int) mSGD.getFocusX(); final int y = (int) mSGD.getFocusY(); ExpandableView underFocus = findView(x, y); if (isFinished && underFocus != null && underFocus != mCurrView) { finishExpanding(false); // @@@ needed? startExpanding(underFocus, BLINDS); mInitialTouchY = y; mHasPopped = false; mLastMotionY = ev.getRawY(); if (isFinished) { mCallback.setUserExpandedChild(mResizedView, expanded); mCallback.expansionStateChanged(false); return false; } else { mCallback.expansionStateChanged(true); } return true; } if (mExpanding) { // Gestural expansion is running updateExpansion(); mLastMotionY = ev.getRawY(); return true; } Loading @@ -396,6 +436,7 @@ public class ExpandHelper implements Gefingerpoken { clearView(); break; } mLastMotionY = ev.getRawY(); return true; } Loading @@ -407,15 +448,16 @@ public class ExpandHelper implements Gefingerpoken { return false; } mExpansionStyle = expandType; if (mExpanding && v == mCurrView) { if (mExpanding && v == mResizedView) { return true; } mExpanding = true; mCallback.expansionStateChanged(true); if (DEBUG) Log.d(TAG, "scale type " + expandType + " beginning on view: " + v); mCallback.setUserLockedChild(v, true); setView(v); mScaler.setView((ExpandableView) v); mScaler.setView(v); mOldHeight = mScaler.getHeight(); mCurrentHeight = mOldHeight; if (mCallback.canChildBeExpanded(v)) { if (DEBUG) Log.d(TAG, "working on an expandable child"); mNaturalHeight = mScaler.getNaturalHeight(mLargeSize); Loading @@ -425,14 +467,13 @@ public class ExpandHelper implements Gefingerpoken { } if (DEBUG) Log.d(TAG, "got mOldHeight: " + mOldHeight + " mNaturalHeight: " + mNaturalHeight); v.getParent().requestDisallowInterceptTouchEvent(true); return true; } private void finishExpanding(boolean force) { if (!mExpanding) return; if (DEBUG) Log.d(TAG, "scale in finishing on view: " + mCurrView); if (DEBUG) Log.d(TAG, "scale in finishing on view: " + mResizedView); float currentHeight = mScaler.getHeight(); float targetHeight = mSmallSize; Loading @@ -446,11 +487,12 @@ public class ExpandHelper implements Gefingerpoken { if (mScaleAnimation.isRunning()) { mScaleAnimation.cancel(); } mCallback.setUserExpandedChild(mCurrView, targetHeight == mNaturalHeight); mCallback.setUserExpandedChild(mResizedView, targetHeight == mNaturalHeight); mCallback.expansionStateChanged(false); if (targetHeight != currentHeight) { mScaleAnimation.setFloatValues(targetHeight); mScaleAnimation.setupStartValues(); final View scaledView = mCurrView; final View scaledView = mResizedView; mScaleAnimation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { Loading @@ -460,7 +502,7 @@ public class ExpandHelper implements Gefingerpoken { }); mScaleAnimation.start(); } else { mCallback.setUserLockedChild(mCurrView, false); mCallback.setUserLockedChild(mResizedView, false); } mExpanding = false; Loading @@ -470,16 +512,11 @@ public class ExpandHelper implements Gefingerpoken { if (DEBUG) Log.d(TAG, "currentHeight is: " + currentHeight); if (DEBUG) Log.d(TAG, "mSmallSize is: " + mSmallSize); if (DEBUG) Log.d(TAG, "targetHeight is: " + targetHeight); if (DEBUG) Log.d(TAG, "scale was finished on view: " + mCurrView); if (DEBUG) Log.d(TAG, "scale was finished on view: " + mResizedView); } private void clearView() { mCurrView = null; } private void setView(View v) { mCurrView = v; mResizedView = null; } /** Loading @@ -493,6 +530,18 @@ public class ExpandHelper implements Gefingerpoken { mSGD = new ScaleGestureDetector(mContext, mScaleGestureListener); } /** * Change the expansion mode to only observe movements and don't perform any resizing. * This is needed when the expanding is finished and the scroller kicks in, * performing an overscroll motion. We only want to shrink it again when we are not * overscrolled. * * @param onlyMovements Should only movements be observed? */ public void onlyObserveMovements(boolean onlyMovements) { mOnlyMovements = onlyMovements; } /** * Triggers haptic feedback. */ Loading
packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java +2 −1 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import android.view.View; import android.view.ViewConfiguration; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import com.android.systemui.ExpandHelper; import com.android.systemui.Gefingerpoken; import com.android.systemui.R; Loading Loading @@ -87,6 +86,7 @@ public class DragDownHelper implements Gefingerpoken { captureStartingChild(mInitialTouchX, mInitialTouchY); mInitialTouchY = y; mInitialTouchX = x; mOnDragDownListener.onTouchSlopExceeded(); return true; } break; Loading Loading @@ -202,5 +202,6 @@ public class DragDownHelper implements Gefingerpoken { void onDraggedDown(View startingChild); void onDragDownReset(); void onThresholdReached(); void onTouchSlopExceeded(); } }
packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +37 −43 Original line number Diff line number Diff line Loading @@ -83,10 +83,7 @@ public class NotificationPanelView extends PanelView implements private float mQsExpansionHeight; private int mQsMinExpansionHeight; private int mQsMaxExpansionHeight; private int mMinStackHeight; private int mQsPeekHeight; private float mNotificationTranslation; private int mStackScrollerIntrinsicPadding; private boolean mStackScrollerOverscrolling; private boolean mQsExpansionEnabled = true; private ValueAnimator mQsExpansionAnimator; Loading Loading @@ -165,7 +162,6 @@ public class NotificationPanelView extends PanelView implements super.loadDimens(); mNotificationTopPadding = getResources().getDimensionPixelSize( R.dimen.notifications_top_padding); mMinStackHeight = getResources().getDimensionPixelSize(R.dimen.collapsed_stack_height); mFlingAnimationUtils = new FlingAnimationUtils(getContext(), 0.4f); mStatusBarMinHeight = getResources().getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); Loading @@ -185,7 +181,8 @@ public class NotificationPanelView extends PanelView implements mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getHeight(); if (mQsExpanded) { if (mQsFullyExpanded) { setQsStackScrollerPadding(mQsMaxExpansionHeight); mQsExpansionHeight = mQsMaxExpansionHeight; requestScrollerTopPaddingUpdate(false /* animate */); } } else { if (!mStackScrollerOverscrolling) { Loading @@ -202,11 +199,12 @@ public class NotificationPanelView extends PanelView implements */ private void positionClockAndNotifications() { boolean animateClock = mNotificationStackScroller.isAddOrRemoveAnimationPending(); int stackScrollerPadding; if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) { int bottom = mStackScrollerOverscrolling ? mHeader.getCollapsedHeight() : mHeader.getBottom(); mStackScrollerIntrinsicPadding = bottom + mQsPeekHeight stackScrollerPadding = bottom + mQsPeekHeight + mNotificationTopPadding; mTopPaddingAdjustment = 0; } else { Loading @@ -224,11 +222,11 @@ public class NotificationPanelView extends PanelView implements mKeyguardStatusView.setY(mClockPositionResult.clockY); } applyClockAlpha(mClockPositionResult.clockAlpha); mStackScrollerIntrinsicPadding = mClockPositionResult.stackScrollerPadding; stackScrollerPadding = mClockPositionResult.stackScrollerPadding; mTopPaddingAdjustment = mClockPositionResult.stackScrollerPaddingAdjustment; } mNotificationStackScroller.setTopPadding(mStackScrollerIntrinsicPadding, mAnimateNextTopPaddingChange || animateClock); mNotificationStackScroller.setIntrinsicPadding(stackScrollerPadding); requestScrollerTopPaddingUpdate(animateClock); mAnimateNextTopPaddingChange = false; } Loading Loading @@ -384,6 +382,7 @@ public class NotificationPanelView extends PanelView implements mInitialTouchX = x; mQsTracking = true; mIntercepting = false; mNotificationStackScroller.removeLongPressCallback(); return true; } break; Loading Loading @@ -523,6 +522,13 @@ public class NotificationPanelView extends PanelView implements updateQsState(); } @Override public void flingTopOverscroll(float velocity, boolean open) { mStackScrollerOverscrolling = false; setQsExpansion(mQsExpansionHeight); flingSettings(velocity, open); } private void onQsExpansionStarted() { onQsExpansionStarted(0); } Loading Loading @@ -554,7 +560,9 @@ public class NotificationPanelView extends PanelView implements mHeader.setExpanded(expandVisually, mStackScrollerOverscrolling); mNotificationStackScroller.setEnabled(!mQsExpanded); mQsPanel.setVisibility(expandVisually ? View.VISIBLE : View.INVISIBLE); mQsContainer.setVisibility(mKeyguardShowing && !mQsExpanded ? View.INVISIBLE : View.VISIBLE); mQsContainer.setVisibility(mKeyguardShowing && !expandVisually ? View.INVISIBLE : View.VISIBLE); mScrollView.setTouchEnabled(mQsExpanded); } Loading @@ -569,9 +577,7 @@ public class NotificationPanelView extends PanelView implements mQsExpansionHeight = height; mHeader.setExpansion(height - mQsPeekHeight); setQsTranslation(height); if (!mStackScrollerOverscrolling) { setQsStackScrollerPadding(height); } requestScrollerTopPaddingUpdate(false /* animate */); mStatusBar.userActivity(); } Loading @@ -579,24 +585,11 @@ public class NotificationPanelView extends PanelView implements mQsContainer.setY(height - mQsContainer.getHeight()); } private void setQsStackScrollerPadding(float height) { float start = height - mScrollView.getScrollY() + mNotificationTopPadding; float stackHeight = mNotificationStackScroller.getHeight() - start; if (stackHeight <= mMinStackHeight) { float overflow = mMinStackHeight - stackHeight; stackHeight = mMinStackHeight; start = mNotificationStackScroller.getHeight() - stackHeight; mNotificationStackScroller.setTranslationY(overflow); mNotificationTranslation = overflow + mScrollView.getScrollY(); } else { mNotificationStackScroller.setTranslationY(0); mNotificationTranslation = mScrollView.getScrollY(); } mNotificationStackScroller.setTopPadding(clampQsStackScrollerPadding((int) start), false); } private int clampQsStackScrollerPadding(int desiredPadding) { return Math.max(desiredPadding, mStackScrollerIntrinsicPadding); private void requestScrollerTopPaddingUpdate(boolean animate) { mNotificationStackScroller.updateTopPadding(mQsExpansionHeight, mScrollView.getScrollY(), mAnimateNextTopPaddingChange || animate); } private void trackMovement(MotionEvent event) { Loading Loading @@ -705,9 +698,11 @@ public class NotificationPanelView extends PanelView implements protected int getMaxPanelHeight() { // TODO: Figure out transition for collapsing when QS is open, adjust height here. int maxPanelHeight = super.getMaxPanelHeight(); int emptyBottomMargin = mStackScrollerContainer.getHeight() - mNotificationStackScroller.getHeight() + mNotificationStackScroller.getEmptyBottomMargin(); int emptyBottomMargin = mNotificationStackScroller.getEmptyBottomMargin(); emptyBottomMargin = (int) Math.max(0, emptyBottomMargin - mNotificationStackScroller.getCurrentOverScrollAmount(true)); emptyBottomMargin += mStackScrollerContainer.getHeight() - mNotificationStackScroller.getHeight(); int maxHeight = maxPanelHeight - emptyBottomMargin - mTopPaddingAdjustment; maxHeight = Math.max(maxHeight, mStatusBarMinHeight); return maxHeight; Loading Loading @@ -814,13 +809,14 @@ public class NotificationPanelView extends PanelView implements @Override protected void onOverExpansionChanged(float overExpansion) { if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) { float currentOverScroll = mNotificationStackScroller.getCurrentOverScrolledPixels(true); float expansionChange = overExpansion - mOverExpansion; expansionChange *= EXPANSION_RUBBER_BAND_EXTRA_FACTOR; mNotificationStackScroller.setOverScrolledPixels(currentOverScroll + expansionChange, true /* onTop */, false /* animate */); super.onOverExpansionChanged(overExpansion); } } @Override Loading @@ -835,7 +831,6 @@ public class NotificationPanelView extends PanelView implements @Override protected void onTrackingStopped(boolean expand) { super.onTrackingStopped(expand); mOverExpansion = 0.0f; mNotificationStackScroller.setOverScrolledPixels(0.0f, true /* onTop */, true /* animate */); if (expand && (mStatusBar.getBarState() == StatusBarState.KEYGUARD || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED)) { Loading @@ -860,8 +855,7 @@ public class NotificationPanelView extends PanelView implements @Override public void onScrollChanged() { if (mQsExpanded) { mNotificationStackScroller.setTranslationY( mNotificationTranslation - mScrollView.getScrollY()); requestScrollerTopPaddingUpdate(false /* animate */); } } Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +6 −5 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ public abstract class PanelView extends FrameLayout { private int mEdgeTapAreaWidth; private float mInitialOffsetOnTouch; private float mExpandedFraction = 0; private float mExpandedHeight = 0; protected float mExpandedHeight = 0; private boolean mJustPeeked; private boolean mClosing; protected boolean mTracking; Loading Loading @@ -369,8 +369,10 @@ public abstract class PanelView extends FrameLayout { protected void fling(float vel, boolean expand) { cancelPeek(); float target = expand ? getMaxPanelHeight() : 0.0f; if (target == mExpandedHeight) { if (target == mExpandedHeight || mOverExpansion > 0) { onExpandingFinished(); mExpandedHeight = target; mOverExpansion = 0.0f; mBar.panelExpansionChanged(this, mExpandedFraction); return; } Loading Loading @@ -459,6 +461,7 @@ public abstract class PanelView extends FrameLayout { overExpansion = Math.max(0, overExpansion); if (overExpansion != mOverExpansion) { onOverExpansionChanged(overExpansion); mOverExpansion = overExpansion; } if (DEBUG) { Loading @@ -469,9 +472,7 @@ public abstract class PanelView extends FrameLayout { mExpandedFraction = Math.min(1f, (fh == 0) ? 0 : mExpandedHeight / fh); } protected void onOverExpansionChanged(float overExpansion) { mOverExpansion = overExpansion; } protected abstract void onOverExpansionChanged(float overExpansion); protected abstract void onHeightUpdated(float expandedHeight); Loading