Heads up notification can now scroll away after it was seen

Previously it would stick to the top forever, which was very
undesirable and unclear.

Fixes: 	62214133
Test: manual, add multiple huns, nothing sticks to the top
Test: add hun when qs expanded
Change-Id: I3338129ced49dacf01c658767aaedd0f1a408c44
This commit is contained in:
Selim Cinek
2017-11-30 12:29:47 +01:00
parent 05013b3772
commit 9b9d6e16bc
6 changed files with 50 additions and 13 deletions

View File

@@ -112,6 +112,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private int mNotificationMaxHeight; private int mNotificationMaxHeight;
private int mNotificationAmbientHeight; private int mNotificationAmbientHeight;
private int mIncreasedPaddingBetweenElements; private int mIncreasedPaddingBetweenElements;
private boolean mMustStayOnScreen;
/** Does this row contain layouts that can adapt to row expansion */ /** Does this row contain layouts that can adapt to row expansion */
private boolean mExpandable; private boolean mExpandable;
@@ -491,6 +492,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
notifyHeightChanged(false /* needsAnimation */); notifyHeightChanged(false /* needsAnimation */);
} }
if (isHeadsUp) { if (isHeadsUp) {
mMustStayOnScreen = true;
setAboveShelf(true); setAboveShelf(true);
} else if (isAboveShelf() != wasAboveShelf) { } else if (isAboveShelf() != wasAboveShelf) {
mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf); mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
@@ -517,6 +519,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
addChildNotification(row, -1); addChildNotification(row, -1);
} }
@Override
public void setHeadsUpIsVisible() {
super.setHeadsUpIsVisible();
mMustStayOnScreen = false;
}
/** /**
* Add a child notification to this view. * Add a child notification to this view.
* *
@@ -1942,7 +1950,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
@Override @Override
public boolean mustStayOnScreen() { public boolean mustStayOnScreen() {
return mIsHeadsUp; return mIsHeadsUp && mMustStayOnScreen;
} }
/** /**

View File

@@ -478,6 +478,9 @@ public abstract class ExpandableView extends FrameLayout {
return false; return false;
} }
public void setHeadsUpIsVisible() {
}
public boolean isChildInGroup() { public boolean isChildInGroup() {
return false; return false;
} }

View File

@@ -94,6 +94,12 @@ public class ExpandableViewState extends ViewState {
public float shadowAlpha; public float shadowAlpha;
public boolean inShelf; public boolean inShelf;
/**
* A state indicating whether a headsup is currently fully visible, even when not scrolled.
* Only valid if the view is heads upped.
*/
public boolean headsUpIsVisible;
/** /**
* How much the child overlaps with the previous child on top. This is used to * How much the child overlaps with the previous child on top. This is used to
* show the background properly when the child on top is translating away. * show the background properly when the child on top is translating away.
@@ -126,6 +132,7 @@ public class ExpandableViewState extends ViewState {
clipTopAmount = svs.clipTopAmount; clipTopAmount = svs.clipTopAmount;
notGoneIndex = svs.notGoneIndex; notGoneIndex = svs.notGoneIndex;
location = svs.location; location = svs.location;
headsUpIsVisible = svs.headsUpIsVisible;
} }
} }
@@ -175,6 +182,10 @@ public class ExpandableViewState extends ViewState {
expandableView.setTransformingInShelf(false); expandableView.setTransformingInShelf(false);
expandableView.setInShelf(inShelf); expandableView.setInShelf(inShelf);
if (headsUpIsVisible) {
expandableView.setHeadsUpIsVisible();
}
} }
} }
@@ -229,6 +240,10 @@ public class ExpandableViewState extends ViewState {
expandableView.setTransformingInShelf(true); expandableView.setTransformingInShelf(true);
} }
expandableView.setInShelf(this.inShelf); expandableView.setInShelf(this.inShelf);
if (headsUpIsVisible) {
expandableView.setHeadsUpIsVisible();
}
} }
private void startHeightAnimation(final ExpandableView child, AnimationProperties properties) { private void startHeightAnimation(final ExpandableView child, AnimationProperties properties) {

View File

@@ -624,7 +624,7 @@ public class NotificationStackScrollLayout extends ViewGroup
if (childViewState == null) { if (childViewState == null) {
return false; return false;
} }
if ((childViewState.location &= ExpandableViewState.VISIBLE_LOCATIONS) == 0) { if ((childViewState.location & ExpandableViewState.VISIBLE_LOCATIONS) == 0) {
return false; return false;
} }
if (row.getVisibility() != View.VISIBLE) { if (row.getVisibility() != View.VISIBLE) {

View File

@@ -135,7 +135,7 @@ public class StackScrollAlgorithm {
for (int i = 0; i < childCount; i++) { for (int i = 0; i < childCount; i++) {
ExpandableView child = algorithmState.visibleChildren.get(i); ExpandableView child = algorithmState.visibleChildren.get(i);
ExpandableViewState state = resultState.getViewStateForView(child); ExpandableViewState state = resultState.getViewStateForView(child);
if (!child.mustStayOnScreen()) { if (!child.mustStayOnScreen() || state.headsUpIsVisible) {
previousNotificationEnd = Math.max(drawStart, previousNotificationEnd); previousNotificationEnd = Math.max(drawStart, previousNotificationEnd);
previousNotificationStart = Math.max(drawStart, previousNotificationStart); previousNotificationStart = Math.max(drawStart, previousNotificationStart);
} }
@@ -378,6 +378,13 @@ public class StackScrollAlgorithm {
boolean isEmptyShadeView = child instanceof EmptyShadeView; boolean isEmptyShadeView = child instanceof EmptyShadeView;
childViewState.location = ExpandableViewState.LOCATION_MAIN_AREA; childViewState.location = ExpandableViewState.LOCATION_MAIN_AREA;
float inset = ambientState.getTopPadding() + ambientState.getStackTranslation();
if (child.mustStayOnScreen() && childViewState.yTranslation >= 0) {
// Even if we're not scrolled away we're in view and we're also not in the
// shelf. We can relax the constraints and let us scroll off the top!
float end = childViewState.yTranslation + childViewState.height + inset;
childViewState.headsUpIsVisible = end < ambientState.getMaxHeadsUpTranslation();
}
if (isDismissView) { if (isDismissView) {
childViewState.yTranslation = Math.min(childViewState.yTranslation, childViewState.yTranslation = Math.min(childViewState.yTranslation,
ambientState.getInnerHeight() - childHeight); ambientState.getInnerHeight() - childHeight);
@@ -396,8 +403,7 @@ public class StackScrollAlgorithm {
Log.wtf(LOG_TAG, "Failed to assign location for child " + i); Log.wtf(LOG_TAG, "Failed to assign location for child " + i);
} }
childViewState.yTranslation += ambientState.getTopPadding() childViewState.yTranslation += inset;
+ ambientState.getStackTranslation();
return currentYPosition; return currentYPosition;
} }
@@ -420,13 +426,14 @@ public class StackScrollAlgorithm {
break; break;
} }
ExpandableViewState childState = resultState.getViewStateForView(row); ExpandableViewState childState = resultState.getViewStateForView(row);
if (topHeadsUpEntry == null) { if (topHeadsUpEntry == null && row.mustStayOnScreen() && !childState.headsUpIsVisible) {
topHeadsUpEntry = row; topHeadsUpEntry = row;
childState.location = ExpandableViewState.LOCATION_FIRST_HUN; childState.location = ExpandableViewState.LOCATION_FIRST_HUN;
} }
boolean isTopEntry = topHeadsUpEntry == row; boolean isTopEntry = topHeadsUpEntry == row;
float unmodifiedEndLocation = childState.yTranslation + childState.height; float unmodifiedEndLocation = childState.yTranslation + childState.height;
if (mIsExpanded) { if (mIsExpanded) {
if (row.mustStayOnScreen() && !childState.headsUpIsVisible) {
// Ensure that the heads up is always visible even when scrolled off // Ensure that the heads up is always visible even when scrolled off
clampHunToTop(ambientState, row, childState); clampHunToTop(ambientState, row, childState);
if (i == 0 && ambientState.isAboveShelf(row)) { if (i == 0 && ambientState.isAboveShelf(row)) {
@@ -435,6 +442,7 @@ public class StackScrollAlgorithm {
childState.hidden = false; childState.hidden = false;
} }
} }
}
if (row.isPinned()) { if (row.isPinned()) {
childState.yTranslation = Math.max(childState.yTranslation, 0); childState.yTranslation = Math.max(childState.yTranslation, 0);
childState.height = Math.max(row.getIntrinsicHeight(), childState.height); childState.height = Math.max(row.getIntrinsicHeight(), childState.height);
@@ -493,6 +501,7 @@ public class StackScrollAlgorithm {
if (childViewState.yTranslation >= shelfStart) { if (childViewState.yTranslation >= shelfStart) {
childViewState.hidden = true; childViewState.hidden = true;
childViewState.inShelf = true; childViewState.inShelf = true;
childViewState.headsUpIsVisible = false;
} }
if (!ambientState.isShadeExpanded()) { if (!ambientState.isShadeExpanded()) {
childViewState.height = (int) (mStatusBarHeight - childViewState.yTranslation); childViewState.height = (int) (mStatusBarHeight - childViewState.yTranslation);
@@ -531,7 +540,8 @@ public class StackScrollAlgorithm {
ExpandableViewState childViewState = resultState.getViewStateForView(child); ExpandableViewState childViewState = resultState.getViewStateForView(child);
int zDistanceBetweenElements = ambientState.getZDistanceBetweenElements(); int zDistanceBetweenElements = ambientState.getZDistanceBetweenElements();
float baseZ = ambientState.getBaseZHeight(); float baseZ = ambientState.getBaseZHeight();
if (child.mustStayOnScreen() && !ambientState.isDozingAndNotPulsing(child) if (child.mustStayOnScreen() && !childViewState.headsUpIsVisible
&& !ambientState.isDozingAndNotPulsing(child)
&& childViewState.yTranslation < ambientState.getTopPadding() && childViewState.yTranslation < ambientState.getTopPadding()
+ ambientState.getStackTranslation()) { + ambientState.getStackTranslation()) {
if (childrenOnTop != 0.0f) { if (childrenOnTop != 0.0f) {

View File

@@ -84,6 +84,7 @@ public class StackScrollState {
viewState.scaleX = view.getScaleX(); viewState.scaleX = view.getScaleX();
viewState.scaleY = view.getScaleY(); viewState.scaleY = view.getScaleY();
viewState.inShelf = false; viewState.inShelf = false;
viewState.headsUpIsVisible = false;
} }
public ExpandableViewState getViewStateForView(View requestedView) { public ExpandableViewState getViewStateForView(View requestedView) {