mIntercepting = false;
break;
}
-
- // Allow closing the whole panel when in SHADE state.
- if (mStatusBarState == StatusBarState.SHADE) {
- return super.onInterceptTouchEvent(event);
- } else {
- return !mQsExpanded && super.onInterceptTouchEvent(event);
- }
+ return super.onInterceptTouchEvent(event);
}
@Override
}
private boolean isInQsArea(float x, float y) {
- return mStatusBarState != StatusBarState.SHADE ||
- (x >= mScrollView.getLeft() && x <= mScrollView.getRight()) &&
- (y <= mNotificationStackScroller.getBottomMostNotificationBottom()
- || y <= mQsContainer.getY() + mQsContainer.getHeight());
+ return (x >= mScrollView.getLeft() && x <= mScrollView.getRight()) &&
+ (y <= mNotificationStackScroller.getBottomMostNotificationBottom()
+ || y <= mQsContainer.getY() + mQsContainer.getHeight());
}
private void handleQsDown(MotionEvent event) {
}
private float calculateQsTopPadding() {
- // We can only do the smoother transition on Keyguard when we also are not collapsing from a
- // scrolled quick settings.
- if (mKeyguardShowing && mScrollYOverride == -1) {
+ if (mKeyguardShowing
+ && (mTwoFingerQsExpand || mIsExpanding && mQsExpandedWhenExpandingStarted)) {
+
+ // Either QS pushes the notifications down when fully expanded, or QS is fully above the
+ // notifications (mostly on tablets). maxNotifications denotes the normal top padding
+ // on Keyguard, maxQs denotes the top padding from the quick settings panel. We need to
+ // take the maximum and linearly interpolate with the panel expansion for a nice motion.
+ int maxNotifications = mClockPositionResult.stackScrollerPadding
+ - mClockPositionResult.stackScrollerPaddingAdjustment
+ - mNotificationTopPadding;
+ int maxQs = getTempQsMaxExpansion();
+ int max = mStatusBarState == StatusBarState.KEYGUARD
+ ? Math.max(maxNotifications, maxQs)
+ : maxQs;
+ return (int) interpolate(getExpandedFraction(),
+ mQsMinExpansionHeight, max);
+ } else if (mKeyguardShowing && mScrollYOverride == -1) {
+
+ // We can only do the smoother transition on Keyguard when we also are not collapsing
+ // from a scrolled quick settings.
return interpolate(getQsExpansionFraction(),
mNotificationStackScroller.getIntrinsicPadding() - mNotificationTopPadding,
mQsMaxExpansionHeight);
private void requestScrollerTopPaddingUpdate(boolean animate) {
mNotificationStackScroller.updateTopPadding(calculateQsTopPadding(),
mScrollView.getScrollY(),
- mAnimateNextTopPaddingChange || animate);
+ mAnimateNextTopPaddingChange || animate,
+ mKeyguardShowing
+ && (mTwoFingerQsExpand || mIsExpanding && mQsExpandedWhenExpandingStarted));
mAnimateNextTopPaddingChange = false;
}
@Override
protected void onHeightUpdated(float expandedHeight) {
- if (!mQsExpanded) {
+ if (!mQsExpanded || mTwoFingerQsExpand || mIsExpanding && mQsExpandedWhenExpandingStarted) {
positionClockAndNotifications();
}
if (mTwoFingerQsExpand || mQsExpanded && !mQsTracking && mQsExpansionAnimator == null
&& !mQsExpansionFromOverscroll) {
- float panelHeightQsCollapsed = mNotificationStackScroller.getIntrinsicPadding()
- + mNotificationStackScroller.getMinStackHeight()
- + mNotificationStackScroller.getNotificationTopPadding();
- float panelHeightQsExpanded = calculatePanelHeightQsExpanded();
- float t = (expandedHeight - panelHeightQsCollapsed)
- / (panelHeightQsExpanded - panelHeightQsCollapsed);
+ float t;
+ if (mKeyguardShowing) {
+
+ // On Keyguard, interpolate the QS expansion linearly to the panel expansion
+ t = expandedHeight / getMaxPanelHeight();
+ } else {
+ // In Shade, interpolate linearly such that QS is closed whenever panel height is
+ // minimum QS expansion + minStackHeight
+ float panelHeightQsCollapsed = mNotificationStackScroller.getIntrinsicPadding()
+ + mNotificationStackScroller.getMinStackHeight()
+ + mNotificationStackScroller.getNotificationTopPadding();
+ float panelHeightQsExpanded = calculatePanelHeightQsExpanded();
+ t = (expandedHeight - panelHeightQsCollapsed)
+ / (panelHeightQsExpanded - panelHeightQsCollapsed);
+ }
setQsExpansion(mQsMinExpansionHeight
+ t * (getTempQsMaxExpansion() - mQsMinExpansionHeight));
}
float notificationHeight = mNotificationStackScroller.getHeight()
- mNotificationStackScroller.getEmptyBottomMargin()
- mNotificationStackScroller.getTopPadding();
- float totalHeight = mQsMaxExpansionHeight + notificationHeight
- + mNotificationStackScroller.getNotificationTopPadding();
+ float totalHeight = Math.max(
+ mQsMaxExpansionHeight + mNotificationStackScroller.getNotificationTopPadding(),
+ mClockPositionResult.stackScrollerPadding - mTopPaddingAdjustment)
+ + notificationHeight;
if (totalHeight > mNotificationStackScroller.getHeight()) {
float fullyCollapsedHeight = mQsMaxExpansionHeight
+ mNotificationStackScroller.getMinStackHeight()
super.onExpandingStarted();
mNotificationStackScroller.onExpansionStarted();
mIsExpanding = true;
- mQsExpandedWhenExpandingStarted = mQsExpanded;
+ mQsExpandedWhenExpandingStarted = mQsFullyExpanded;
if (mQsExpanded) {
onQsExpansionStarted();
}
@Override
protected void onTrackingStarted() {
super.onTrackingStarted();
+ if (mQsFullyExpanded) {
+ mTwoFingerQsExpand = true;
+ }
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
|| mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
mAfforanceHelper.animateHideLeftRightIcon();
- } else if (mQsExpanded) {
- mTwoFingerQsExpand = true;
}
}
private SwipeHelper mSwipeHelper;
private boolean mSwipingInProgress;
private int mCurrentStackHeight = Integer.MAX_VALUE;
+
+ /**
+ * mCurrentStackHeight is the actual stack height, mLastSetStackHeight is the stack height set
+ * externally from {@link #setStackHeight}
+ */
+ private float mLastSetStackHeight;
private int mOwnScrollY;
private int mMaxLayoutHeight;
* @param height the new height of the stack
*/
public void setStackHeight(float height) {
+ mLastSetStackHeight = height;
setIsExpanded(height > 0.0f);
int newStackHeight = (int) height;
int minStackHeight = getMinStackHeight();
&& initialVelocity > 0;
}
- public void updateTopPadding(float qsHeight, int scrollY, boolean animate) {
+ /**
+ * Updates the top padding of the notifications, taking {@link #getIntrinsicPadding()} into
+ * account.
+ *
+ * @param qsHeight the top padding imposed by the quick settings panel
+ * @param scrollY how much the notifications are scrolled inside the QS/notifications scroll
+ * container
+ * @param animate whether to animate the change
+ * @param ignoreIntrinsicPadding if true, {@link #getIntrinsicPadding()} is ignored and
+ * {@code qsHeight} is the final top padding
+ */
+ public void updateTopPadding(float qsHeight, int scrollY, boolean animate,
+ boolean ignoreIntrinsicPadding) {
float start = qsHeight - scrollY + mNotificationTopPadding;
float stackHeight = getHeight() - start;
int minStackHeight = getMinStackHeight();
float overflow = minStackHeight - stackHeight;
stackHeight = minStackHeight;
start = getHeight() - stackHeight;
- setTranslationY(overflow);
mTopPaddingOverflow = overflow;
} else {
- setTranslationY(0);
mTopPaddingOverflow = 0;
}
- setTopPadding(clampPadding((int) start), animate);
+ setTopPadding(ignoreIntrinsicPadding ? (int) start : clampPadding((int) start),
+ animate);
+ setStackHeight(mLastSetStackHeight);
}
public int getNotificationTopPadding() {