Adjusted the behavior when expanding the notification panel
The topmost notification is now not collapsed anymore but slides in expanded from the top. Therefore it's layout doesn't need to animate anymore. This also cleans up a lot of code in the algorithm which was depending on this resizing which isn't needed anymore. In order to have that transition working perfectly, the padding when collapsing a card is now the same as the slowdown length. Also improved the logic when notification contents are allowed to animate and when not. Also fixed a bug where the top notification was cut off when QS was expanded. Bug: 27402534 Bug: 18434284 Change-Id: I31afa199d38d94e74fd45500c2236ffdb51d989d
This commit is contained in:
@@ -326,9 +326,6 @@
|
||||
<!-- The minimum amount of top overscroll to go to the quick settings. -->
|
||||
<dimen name="min_top_overscroll_to_qs">36dp</dimen>
|
||||
|
||||
<!-- The padding to the second card when the notifications collapse. -->
|
||||
<dimen name="notification_collapse_second_card_padding">8dp</dimen>
|
||||
|
||||
<!-- The height of the speed bump view. -->
|
||||
<dimen name="speed_bump_height">16dp</dimen>
|
||||
|
||||
|
||||
@@ -92,7 +92,14 @@ public class NotificationContentView extends FrameLayout {
|
||||
= new ViewTreeObserver.OnPreDrawListener() {
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
mAnimate = true;
|
||||
// We need to post since we don't want the notification to animate on the very first
|
||||
// frame
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mAnimate = true;
|
||||
}
|
||||
});
|
||||
getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1397,7 +1397,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
// In Shade, interpolate linearly such that QS is closed whenever panel height is
|
||||
// minimum QS expansion + minStackHeight
|
||||
float panelHeightQsCollapsed = mNotificationStackScroller.getIntrinsicPadding()
|
||||
+ mNotificationStackScroller.getMinStackHeight();
|
||||
+ mNotificationStackScroller.getLayoutMinHeight();
|
||||
float panelHeightQsExpanded = calculatePanelHeightQsExpanded();
|
||||
t = (expandedHeight - panelHeightQsCollapsed)
|
||||
/ (panelHeightQsExpanded - panelHeightQsCollapsed);
|
||||
@@ -1453,7 +1453,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
&& mShadeEmpty) {
|
||||
notificationHeight = mNotificationStackScroller.getEmptyShadeViewHeight()
|
||||
+ mNotificationStackScroller.getBottomStackPeekSize()
|
||||
+ mNotificationStackScroller.getCollapseSecondCardPadding();
|
||||
+ mNotificationStackScroller.getBottomStackSlowDownHeight();
|
||||
}
|
||||
int maxQsHeight = mQsMaxExpansionHeight;
|
||||
|
||||
@@ -1468,7 +1468,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
+ notificationHeight;
|
||||
if (totalHeight > mNotificationStackScroller.getHeight()) {
|
||||
float fullyCollapsedHeight = maxQsHeight
|
||||
+ mNotificationStackScroller.getMinStackHeight();
|
||||
+ mNotificationStackScroller.getLayoutMinHeight();
|
||||
totalHeight = Math.max(fullyCollapsedHeight, mNotificationStackScroller.getHeight());
|
||||
}
|
||||
return (int) totalHeight;
|
||||
@@ -1485,7 +1485,7 @@ public class NotificationPanelView extends PanelView implements
|
||||
private float getFadeoutAlpha() {
|
||||
float alpha = (getNotificationsTopY() + mNotificationStackScroller.getFirstItemMinHeight())
|
||||
/ (mQsMinExpansionHeight + mNotificationStackScroller.getBottomStackPeekSize()
|
||||
- mNotificationStackScroller.getCollapseSecondCardPadding());
|
||||
- mNotificationStackScroller.getBottomStackSlowDownHeight());
|
||||
alpha = Math.max(0, Math.min(alpha, 1));
|
||||
alpha = (float) Math.pow(alpha, 0.75);
|
||||
return alpha;
|
||||
|
||||
@@ -418,12 +418,9 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
.getDimensionPixelSize(R.dimen.notification_divider_height));
|
||||
mIncreasedPaddingBetweenElements = context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.notification_divider_height_increased);
|
||||
|
||||
mBottomStackSlowDownHeight = mStackScrollAlgorithm.getBottomStackSlowDownLength();
|
||||
mMinTopOverScrollToEscape = getResources().getDimensionPixelSize(
|
||||
R.dimen.min_top_overscroll_to_qs);
|
||||
mCollapseSecondCardPadding = getResources().getDimensionPixelSize(
|
||||
R.dimen.notification_collapse_second_card_padding);
|
||||
}
|
||||
|
||||
private void notifyHeightChangeListener(ExpandableView view) {
|
||||
@@ -508,14 +505,6 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
mAmbientState.setTopPadding(mTopPadding);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether the height of the layout needs to be adapted, in order to ensure that the
|
||||
* last child is not in the bottom stack.
|
||||
*/
|
||||
private boolean needsHeightAdaption() {
|
||||
return getNotGoneChildCount() > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the children views according to the stack scroll algorithm. Call this whenever
|
||||
* modifications to {@link #mOwnScrollY} are performed to reflect it in the view layout.
|
||||
@@ -599,7 +588,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
mLastSetStackHeight = height;
|
||||
setIsExpanded(height > 0.0f);
|
||||
int newStackHeight = (int) height;
|
||||
int minStackHeight = getMinStackHeight();
|
||||
int minStackHeight = getLayoutMinHeight();
|
||||
int stackHeight;
|
||||
float paddingOffset;
|
||||
boolean trackingHeadsUp = mTrackingHeadsUp || mHeadsUpManager.hasPinnedHeadsUp();
|
||||
@@ -612,20 +601,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
stackHeight = newStackHeight;
|
||||
} else {
|
||||
int translationY;
|
||||
if (!trackingHeadsUp) {
|
||||
// We did not reach the position yet where we actually start growing,
|
||||
// so we translate the stack upwards.
|
||||
translationY = (newStackHeight - minStackHeight);
|
||||
// A slight parallax effect is introduced in order for the stack to catch up with
|
||||
// the top card.
|
||||
float partiallyThere = (newStackHeight - mTopPadding - mTopPaddingOverflow)
|
||||
/ minStackHeight;
|
||||
partiallyThere = Math.max(0, partiallyThere);
|
||||
translationY += (1 - partiallyThere) * (mBottomStackPeekSize +
|
||||
mCollapseSecondCardPadding);
|
||||
} else {
|
||||
translationY = (int) (height - normalUnfoldPositionStart);
|
||||
}
|
||||
translationY = newStackHeight - normalUnfoldPositionStart;
|
||||
paddingOffset = translationY - mTopPadding;
|
||||
stackHeight = (int) (height - (translationY - mTopPadding));
|
||||
}
|
||||
@@ -668,8 +644,8 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
return mBottomStackPeekSize;
|
||||
}
|
||||
|
||||
public int getCollapseSecondCardPadding() {
|
||||
return mCollapseSecondCardPadding;
|
||||
public int getBottomStackSlowDownHeight() {
|
||||
return mBottomStackSlowDownHeight;
|
||||
}
|
||||
|
||||
public void setLongPressListener(SwipeHelper.LongPressListener listener) {
|
||||
@@ -1850,7 +1826,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
boolean ignoreIntrinsicPadding) {
|
||||
float start = qsHeight;
|
||||
float stackHeight = getHeight() - start;
|
||||
int minStackHeight = getMinStackHeight();
|
||||
int minStackHeight = getLayoutMinHeight();
|
||||
if (stackHeight <= minStackHeight) {
|
||||
float overflow = minStackHeight - stackHeight;
|
||||
stackHeight = minStackHeight;
|
||||
@@ -1864,11 +1840,16 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
setStackHeight(mLastSetStackHeight);
|
||||
}
|
||||
|
||||
public int getMinStackHeight() {
|
||||
public int getLayoutMinHeight() {
|
||||
final ExpandableView firstChild = getFirstChildNotGone();
|
||||
final int firstChildMinHeight = firstChild != null ? firstChild.getMinHeight()
|
||||
int firstChildMinHeight = firstChild != null
|
||||
? firstChild.getIntrinsicHeight()
|
||||
: mCollapsedSize;
|
||||
return firstChildMinHeight + mBottomStackPeekSize + mCollapseSecondCardPadding;
|
||||
if (mOwnScrollY > 0) {
|
||||
firstChildMinHeight = Math.max(firstChildMinHeight - mOwnScrollY, mCollapsedSize);
|
||||
}
|
||||
return Math.min(firstChildMinHeight + mBottomStackPeekSize + mBottomStackSlowDownHeight,
|
||||
mMaxLayoutHeight - mTopPadding);
|
||||
}
|
||||
|
||||
public float getTopPaddingOverflow() {
|
||||
@@ -1880,7 +1861,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
final int firstChildMinHeight = firstChild != null ? (int) firstChild.getMinHeight()
|
||||
: mCollapsedSize;
|
||||
return mIntrinsicPadding + firstChildMinHeight + mBottomStackPeekSize
|
||||
+ mCollapseSecondCardPadding;
|
||||
+ mBottomStackSlowDownHeight;
|
||||
}
|
||||
|
||||
private int clampPadding(int desiredPadding) {
|
||||
@@ -1994,7 +1975,6 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
|
||||
private void onViewRemovedInternal(View child) {
|
||||
mStackScrollAlgorithm.notifyChildrenChanged(this);
|
||||
if (mChangePositionInProgress) {
|
||||
// This is only a position change, don't do anything special
|
||||
return;
|
||||
@@ -2175,7 +2155,6 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
|
||||
private void onViewAddedInternal(View child) {
|
||||
updateHideSensitiveForChild(child);
|
||||
mStackScrollAlgorithm.notifyChildrenChanged(this);
|
||||
((ExpandableView) child).setOnHeightChangedListener(this);
|
||||
generateAddAnimation(child, false /* fromMoreCard */);
|
||||
updateAnimationState(child);
|
||||
@@ -2643,12 +2622,8 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
|
||||
public int getEmptyBottomMargin() {
|
||||
int emptyMargin = mMaxLayoutHeight - mContentHeight - mBottomStackPeekSize;
|
||||
if (needsHeightAdaption()) {
|
||||
emptyMargin -= mBottomStackSlowDownHeight;
|
||||
} else {
|
||||
emptyMargin -= mCollapseSecondCardPadding;
|
||||
}
|
||||
int emptyMargin = mMaxLayoutHeight - mContentHeight - mBottomStackPeekSize
|
||||
- mBottomStackSlowDownHeight;
|
||||
return Math.max(emptyMargin, 0);
|
||||
}
|
||||
|
||||
@@ -2659,12 +2634,10 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
|
||||
public void onExpansionStarted() {
|
||||
mIsExpansionChanging = true;
|
||||
mStackScrollAlgorithm.onExpansionStarted(mCurrentStackScrollState);
|
||||
}
|
||||
|
||||
public void onExpansionStopped() {
|
||||
mIsExpansionChanging = false;
|
||||
mStackScrollAlgorithm.onExpansionStopped();
|
||||
if (!mIsExpanded) {
|
||||
mOwnScrollY = 0;
|
||||
|
||||
@@ -2732,7 +2705,6 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
if (mIsExpanded && mAnimationsEnabled) {
|
||||
mRequestViewResizeAnimationOnLayout = true;
|
||||
}
|
||||
mStackScrollAlgorithm.onReset(view);
|
||||
updateAnimationState(view);
|
||||
updateChronometerForChild(view);
|
||||
}
|
||||
@@ -3163,15 +3135,7 @@ public class NotificationStackScrollLayout extends ViewGroup
|
||||
}
|
||||
|
||||
public int getDismissViewHeight() {
|
||||
int height = mDismissView.getHeight() + mPaddingBetweenElements;
|
||||
|
||||
// Hack: Accommodate for additional distance when we only have one notification and the
|
||||
// dismiss all button.
|
||||
if (getNotGoneChildCount() == 2 && getLastChildNotGone() == mDismissView
|
||||
&& getFirstChildNotGone() instanceof ActivatableNotificationView) {
|
||||
height += mCollapseSecondCardPadding;
|
||||
}
|
||||
return height;
|
||||
return mDismissView.getHeight() + mPaddingBetweenElements;
|
||||
}
|
||||
|
||||
public int getEmptyShadeViewHeight() {
|
||||
|
||||
@@ -52,13 +52,8 @@ public class StackScrollAlgorithm {
|
||||
private StackIndentationFunctor mBottomStackIndentationFunctor;
|
||||
|
||||
private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
|
||||
private boolean mIsExpansionChanging;
|
||||
private int mFirstChildMaxHeight;
|
||||
private boolean mIsExpanded;
|
||||
private ExpandableView mFirstChildWhileExpanding;
|
||||
private boolean mExpandedOnStart;
|
||||
private int mBottomStackSlowDownLength;
|
||||
private int mCollapseSecondCardPadding;
|
||||
|
||||
public StackScrollAlgorithm(Context context) {
|
||||
initView(context);
|
||||
@@ -86,8 +81,6 @@ public class StackScrollAlgorithm {
|
||||
mZBasicHeight = (MAX_ITEMS_IN_BOTTOM_STACK + 1) * mZDistanceBetweenElements;
|
||||
mBottomStackSlowDownLength = context.getResources()
|
||||
.getDimensionPixelSize(R.dimen.bottom_stack_slow_down_length);
|
||||
mCollapseSecondCardPadding = context.getResources().getDimensionPixelSize(
|
||||
R.dimen.notification_collapse_second_card_padding);
|
||||
mBottomStackIndentationFunctor = new PiecewiseLinearIndentationFunctor(
|
||||
MAX_ITEMS_IN_BOTTOM_STACK,
|
||||
mBottomStackPeekSize,
|
||||
@@ -508,7 +501,7 @@ public class StackScrollAlgorithm {
|
||||
int childHeight, int minHeight, AmbientState ambientState) {
|
||||
|
||||
int bottomStackStart = ambientState.getInnerHeight()
|
||||
- mBottomStackPeekSize - mCollapseSecondCardPadding;
|
||||
- mBottomStackPeekSize - mBottomStackSlowDownLength;
|
||||
int childStart = bottomStackStart - childHeight;
|
||||
if (childStart < childViewState.yTranslation) {
|
||||
float newHeight = bottomStackStart - childViewState.yTranslation;
|
||||
@@ -595,12 +588,9 @@ public class StackScrollAlgorithm {
|
||||
|
||||
// The starting position of the bottom stack peek
|
||||
int bottomPeekStart = ambientState.getInnerHeight() - mBottomStackPeekSize -
|
||||
mCollapseSecondCardPadding + ambientState.getScrollY();
|
||||
mBottomStackSlowDownLength + ambientState.getScrollY();
|
||||
// Collapse and expand the first child while the shade is being expanded
|
||||
float maxHeight = mIsExpansionChanging && child == mFirstChildWhileExpanding
|
||||
? mFirstChildMaxHeight
|
||||
: childHeight;
|
||||
childViewState.height = (int) Math.max(Math.min(bottomPeekStart, maxHeight),
|
||||
childViewState.height = (int) Math.max(Math.min(bottomPeekStart, (float) childHeight),
|
||||
child.getMinHeight());
|
||||
}
|
||||
|
||||
@@ -656,55 +646,6 @@ public class StackScrollAlgorithm {
|
||||
}
|
||||
}
|
||||
|
||||
public void onExpansionStarted(StackScrollState currentState) {
|
||||
mIsExpansionChanging = true;
|
||||
mExpandedOnStart = mIsExpanded;
|
||||
ViewGroup hostView = currentState.getHostView();
|
||||
updateFirstChildHeightWhileExpanding(hostView);
|
||||
}
|
||||
|
||||
private void updateFirstChildHeightWhileExpanding(ViewGroup hostView) {
|
||||
mFirstChildWhileExpanding = (ExpandableView) findFirstVisibleChild(hostView);
|
||||
if (mFirstChildWhileExpanding != null) {
|
||||
if (mExpandedOnStart) {
|
||||
|
||||
// We are collapsing the shade, so the first child can get as most as high as the
|
||||
// current height or the end value of the animation.
|
||||
mFirstChildMaxHeight = StackStateAnimator.getFinalActualHeight(
|
||||
mFirstChildWhileExpanding);
|
||||
} else {
|
||||
updateFirstChildMaxSizeToMaxHeight();
|
||||
}
|
||||
} else {
|
||||
mFirstChildMaxHeight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateFirstChildMaxSizeToMaxHeight() {
|
||||
// We are expanding the shade, expand it to its full height.
|
||||
if (!isMaxSizeInitialized(mFirstChildWhileExpanding)) {
|
||||
|
||||
// This child was not layouted yet, wait for a layout pass
|
||||
mFirstChildWhileExpanding
|
||||
.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
|
||||
@Override
|
||||
public void onLayoutChange(View v, int left, int top, int right,
|
||||
int bottom, int oldLeft, int oldTop, int oldRight,
|
||||
int oldBottom) {
|
||||
if (mFirstChildWhileExpanding != null) {
|
||||
mFirstChildMaxHeight = getMaxAllowedChildHeight(
|
||||
mFirstChildWhileExpanding);
|
||||
} else {
|
||||
mFirstChildMaxHeight = 0;
|
||||
}
|
||||
v.removeOnLayoutChangeListener(this);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
mFirstChildMaxHeight = getMaxAllowedChildHeight(mFirstChildWhileExpanding);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMaxSizeInitialized(ExpandableView child) {
|
||||
if (child instanceof ExpandableNotificationRow) {
|
||||
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
|
||||
@@ -724,32 +665,10 @@ public class StackScrollAlgorithm {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onExpansionStopped() {
|
||||
mIsExpansionChanging = false;
|
||||
mFirstChildWhileExpanding = null;
|
||||
}
|
||||
|
||||
public void setIsExpanded(boolean isExpanded) {
|
||||
this.mIsExpanded = isExpanded;
|
||||
}
|
||||
|
||||
public void notifyChildrenChanged(final NotificationStackScrollLayout hostView) {
|
||||
if (mIsExpansionChanging) {
|
||||
hostView.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateFirstChildHeightWhileExpanding(hostView);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void onReset(ExpandableView view) {
|
||||
if (view.equals(mFirstChildWhileExpanding)) {
|
||||
updateFirstChildMaxSizeToMaxHeight();
|
||||
}
|
||||
}
|
||||
|
||||
class StackScrollAlgorithmState {
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user