Merge "Fix bottom hun content position" into tm-dev am: ed9fecc216

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17202660

Change-Id: Ic6967abab256cd55a895cf99214a2d8854bdebad
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Lyn Han
2022-04-05 16:50:51 +00:00
committed by Automerger Merge Worker
4 changed files with 76 additions and 43 deletions

View File

@@ -23,6 +23,7 @@
<item type="id" name="scale_x_animator_tag"/> <item type="id" name="scale_x_animator_tag"/>
<item type="id" name="scale_y_animator_tag"/> <item type="id" name="scale_y_animator_tag"/>
<item type="id" name="top_inset_animator_tag"/> <item type="id" name="top_inset_animator_tag"/>
<item type="id" name="bottom_inset_animator_tag"/>
<item type="id" name="height_animator_tag"/> <item type="id" name="height_animator_tag"/>
<item type="id" name="x_animator_tag"/> <item type="id" name="x_animator_tag"/>
<item type="id" name="y_animator_tag"/> <item type="id" name="y_animator_tag"/>
@@ -33,6 +34,7 @@
<item type="id" name="scale_y_animator_end_value_tag"/> <item type="id" name="scale_y_animator_end_value_tag"/>
<item type="id" name="alpha_animator_end_value_tag"/> <item type="id" name="alpha_animator_end_value_tag"/>
<item type="id" name="top_inset_animator_end_value_tag"/> <item type="id" name="top_inset_animator_end_value_tag"/>
<item type="id" name="bottom_inset_animator_end_value_tag"/>
<item type="id" name="height_animator_end_value_tag"/> <item type="id" name="height_animator_end_value_tag"/>
<item type="id" name="x_animator_tag_end_value"/> <item type="id" name="x_animator_tag_end_value"/>
<item type="id" name="y_animator_tag_end_value"/> <item type="id" name="y_animator_tag_end_value"/>
@@ -43,6 +45,7 @@
<item type="id" name="scale_y_animator_start_value_tag"/> <item type="id" name="scale_y_animator_start_value_tag"/>
<item type="id" name="alpha_animator_start_value_tag"/> <item type="id" name="alpha_animator_start_value_tag"/>
<item type="id" name="top_inset_animator_start_value_tag"/> <item type="id" name="top_inset_animator_start_value_tag"/>
<item type="id" name="bottom_inset_animator_start_value_tag"/>
<item type="id" name="height_animator_start_value_tag"/> <item type="id" name="height_animator_start_value_tag"/>
<item type="id" name="x_animator_tag_start_value"/> <item type="id" name="x_animator_tag_start_value"/>
<item type="id" name="y_animator_tag_start_value"/> <item type="id" name="y_animator_tag_start_value"/>

View File

@@ -594,17 +594,14 @@ public class NotificationShelf extends ActivatableNotificationView implements
} else { } else {
shouldClipOwnTop = view.showingPulsing(); shouldClipOwnTop = view.showingPulsing();
} }
if (viewEnd > notificationClipEnd && !shouldClipOwnTop if (!isPinned) {
&& (mAmbientState.isShadeExpanded() || !isPinned)) { if (viewEnd > notificationClipEnd && !shouldClipOwnTop) {
int clipBottomAmount = (int) (viewEnd - notificationClipEnd); int clipBottomAmount = (int) (viewEnd - notificationClipEnd);
if (isPinned) {
clipBottomAmount = Math.min(view.getIntrinsicHeight() - view.getCollapsedHeight(),
clipBottomAmount);
}
view.setClipBottomAmount(clipBottomAmount); view.setClipBottomAmount(clipBottomAmount);
} else { } else {
view.setClipBottomAmount(0); view.setClipBottomAmount(0);
} }
}
if (shouldClipOwnTop) { if (shouldClipOwnTop) {
return (int) (viewEnd - getTranslationY()); return (int) (viewEnd - getTranslationY());
} else { } else {

View File

@@ -34,10 +34,13 @@ public class ExpandableViewState extends ViewState {
private static final int TAG_ANIMATOR_HEIGHT = R.id.height_animator_tag; private static final int TAG_ANIMATOR_HEIGHT = R.id.height_animator_tag;
private static final int TAG_ANIMATOR_TOP_INSET = R.id.top_inset_animator_tag; private static final int TAG_ANIMATOR_TOP_INSET = R.id.top_inset_animator_tag;
private static final int TAG_ANIMATOR_BOTTOM_INSET = R.id.bottom_inset_animator_tag;
private static final int TAG_END_HEIGHT = R.id.height_animator_end_value_tag; private static final int TAG_END_HEIGHT = R.id.height_animator_end_value_tag;
private static final int TAG_END_TOP_INSET = R.id.top_inset_animator_end_value_tag; private static final int TAG_END_TOP_INSET = R.id.top_inset_animator_end_value_tag;
private static final int TAG_END_BOTTOM_INSET = R.id.bottom_inset_animator_end_value_tag;
private static final int TAG_START_HEIGHT = R.id.height_animator_start_value_tag; private static final int TAG_START_HEIGHT = R.id.height_animator_start_value_tag;
private static final int TAG_START_TOP_INSET = R.id.top_inset_animator_start_value_tag; private static final int TAG_START_TOP_INSET = R.id.top_inset_animator_start_value_tag;
private static final int TAG_START_BOTTOM_INSET = R.id.bottom_inset_animator_start_value_tag;
// These are flags such that we can create masks for filtering. // These are flags such that we can create masks for filtering.
@@ -96,11 +99,16 @@ public class ExpandableViewState extends ViewState {
public boolean headsUpIsVisible; public boolean headsUpIsVisible;
/** /**
* How much the child overlaps with the previous child on top. This is used to * How much the child overlaps on top with the child above.
* show the background properly when the child on top is translating away.
*/ */
public int clipTopAmount; public int clipTopAmount;
/**
* How much the child overlaps on bottom with the child above. This is used to
* show the background properly when the child on top is translating away.
*/
public int clipBottomAmount;
/** /**
* The index of the view, only accounting for views not equal to GONE * The index of the view, only accounting for views not equal to GONE
*/ */
@@ -138,8 +146,8 @@ public class ExpandableViewState extends ViewState {
if (view instanceof ExpandableView) { if (view instanceof ExpandableView) {
ExpandableView expandableView = (ExpandableView) view; ExpandableView expandableView = (ExpandableView) view;
int height = expandableView.getActualHeight(); final int height = expandableView.getActualHeight();
int newHeight = this.height; final int newHeight = this.height;
// apply height // apply height
if (height != newHeight) { if (height != newHeight) {
@@ -157,10 +165,14 @@ public class ExpandableViewState extends ViewState {
expandableView.setBelowSpeedBump(this.belowSpeedBump); expandableView.setBelowSpeedBump(this.belowSpeedBump);
// apply clipping // apply clipping
float oldClipTopAmount = expandableView.getClipTopAmount(); final float oldClipTopAmount = expandableView.getClipTopAmount();
if (oldClipTopAmount != this.clipTopAmount) { if (oldClipTopAmount != this.clipTopAmount) {
expandableView.setClipTopAmount(this.clipTopAmount); expandableView.setClipTopAmount(this.clipTopAmount);
} }
final float oldClipBottomAmount = expandableView.getClipBottomAmount();
if (oldClipBottomAmount != this.clipBottomAmount) {
expandableView.setClipBottomAmount(this.clipBottomAmount);
}
expandableView.setTransformingInShelf(false); expandableView.setTransformingInShelf(false);
expandableView.setInShelf(inShelf); expandableView.setInShelf(inShelf);
@@ -187,13 +199,20 @@ public class ExpandableViewState extends ViewState {
abortAnimation(child, TAG_ANIMATOR_HEIGHT); abortAnimation(child, TAG_ANIMATOR_HEIGHT);
} }
// start top inset animation // start clip top animation
if (this.clipTopAmount != expandableView.getClipTopAmount()) { if (this.clipTopAmount != expandableView.getClipTopAmount()) {
startInsetAnimation(expandableView, properties); startClipAnimation(expandableView, properties, /* clipTop */true);
} else { } else {
abortAnimation(child, TAG_ANIMATOR_TOP_INSET); abortAnimation(child, TAG_ANIMATOR_TOP_INSET);
} }
// start clip bottom animation
if (this.clipBottomAmount != expandableView.getClipBottomAmount()) {
startClipAnimation(expandableView, properties, /* clipTop */ false);
} else {
abortAnimation(child, TAG_ANIMATOR_BOTTOM_INSET);
}
// start dimmed animation // start dimmed animation
expandableView.setDimmed(this.dimmed, animationFilter.animateDimmed); expandableView.setDimmed(this.dimmed, animationFilter.animateDimmed);
@@ -301,16 +320,20 @@ public class ExpandableViewState extends ViewState {
child.setActualHeightAnimating(true); child.setActualHeightAnimating(true);
} }
private void startInsetAnimation(final ExpandableView child, AnimationProperties properties) { private void startClipAnimation(final ExpandableView child, AnimationProperties properties,
Integer previousStartValue = getChildTag(child, TAG_START_TOP_INSET); boolean clipTop) {
Integer previousEndValue = getChildTag(child, TAG_END_TOP_INSET); Integer previousStartValue = getChildTag(child,
int newEndValue = this.clipTopAmount; clipTop ? TAG_START_TOP_INSET : TAG_START_BOTTOM_INSET);
Integer previousEndValue = getChildTag(child,
clipTop ? TAG_END_TOP_INSET : TAG_END_BOTTOM_INSET);
int newEndValue = clipTop ? this.clipTopAmount : this.clipBottomAmount;
if (previousEndValue != null && previousEndValue == newEndValue) { if (previousEndValue != null && previousEndValue == newEndValue) {
return; return;
} }
ValueAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_TOP_INSET); ValueAnimator previousAnimator = getChildTag(child,
clipTop ? TAG_ANIMATOR_TOP_INSET : TAG_ANIMATOR_BOTTOM_INSET);
AnimationFilter filter = properties.getAnimationFilter(); AnimationFilter filter = properties.getAnimationFilter();
if (!filter.animateTopInset) { if (clipTop && !filter.animateTopInset || !clipTop) {
// just a local update was performed // just a local update was performed
if (previousAnimator != null) { if (previousAnimator != null) {
// we need to increase all animation keyframes of the previous animator by the // we need to increase all animation keyframes of the previous animator by the
@@ -319,22 +342,28 @@ public class ExpandableViewState extends ViewState {
int relativeDiff = newEndValue - previousEndValue; int relativeDiff = newEndValue - previousEndValue;
int newStartValue = previousStartValue + relativeDiff; int newStartValue = previousStartValue + relativeDiff;
values[0].setIntValues(newStartValue, newEndValue); values[0].setIntValues(newStartValue, newEndValue);
child.setTag(TAG_START_TOP_INSET, newStartValue); child.setTag(clipTop ? TAG_START_TOP_INSET : TAG_START_BOTTOM_INSET, newStartValue);
child.setTag(TAG_END_TOP_INSET, newEndValue); child.setTag(clipTop ? TAG_END_TOP_INSET : TAG_END_BOTTOM_INSET, newEndValue);
previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
return; return;
} else { } else {
// no new animation needed, let's just apply the value // no new animation needed, let's just apply the value
if (clipTop) {
child.setClipTopAmount(newEndValue); child.setClipTopAmount(newEndValue);
} else {
child.setClipBottomAmount(newEndValue);
}
return; return;
} }
} }
ValueAnimator animator = ValueAnimator.ofInt(child.getClipTopAmount(), newEndValue); ValueAnimator animator = ValueAnimator.ofInt(
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { clipTop ? child.getClipTopAmount() : child.getClipBottomAmount(), newEndValue);
@Override animator.addUpdateListener(animation -> {
public void onAnimationUpdate(ValueAnimator animation) { if (clipTop) {
child.setClipTopAmount((int) animation.getAnimatedValue()); child.setClipTopAmount((int) animation.getAnimatedValue());
} else {
child.setClipBottomAmount((int) animation.getAnimatedValue());
} }
}); });
animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
@@ -353,15 +382,16 @@ public class ExpandableViewState extends ViewState {
animator.addListener(new AnimatorListenerAdapter() { animator.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
child.setTag(TAG_ANIMATOR_TOP_INSET, null); child.setTag(clipTop ? TAG_ANIMATOR_TOP_INSET : TAG_ANIMATOR_BOTTOM_INSET, null);
child.setTag(TAG_START_TOP_INSET, null); child.setTag(clipTop ? TAG_START_TOP_INSET : TAG_START_BOTTOM_INSET, null);
child.setTag(TAG_END_TOP_INSET, null); child.setTag(clipTop ? TAG_END_TOP_INSET : TAG_END_BOTTOM_INSET, null);
} }
}); });
startAnimator(animator, listener); startAnimator(animator, listener);
child.setTag(TAG_ANIMATOR_TOP_INSET, animator); child.setTag(clipTop ? TAG_ANIMATOR_TOP_INSET:TAG_ANIMATOR_BOTTOM_INSET, animator);
child.setTag(TAG_START_TOP_INSET, child.getClipTopAmount()); child.setTag(clipTop ? TAG_START_TOP_INSET: TAG_START_BOTTOM_INSET,
child.setTag(TAG_END_TOP_INSET, newEndValue); clipTop ? child.getClipTopAmount() : child.getClipBottomAmount());
child.setTag(clipTop ? TAG_END_TOP_INSET: TAG_END_BOTTOM_INSET, newEndValue);
} }
/** /**

View File

@@ -192,6 +192,7 @@ public class StackScrollAlgorithm {
float clipStart = 0; float clipStart = 0;
int childCount = algorithmState.visibleChildren.size(); int childCount = algorithmState.visibleChildren.size();
boolean firstHeadsUp = true; boolean firstHeadsUp = true;
float firstHeadsUpEnd = 0;
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 = child.getViewState(); ExpandableViewState state = child.getViewState();
@@ -203,14 +204,18 @@ public class StackScrollAlgorithm {
float newNotificationEnd = newYTranslation + newHeight; float newNotificationEnd = newYTranslation + newHeight;
boolean isHeadsUp = (child instanceof ExpandableNotificationRow) && child.isPinned(); boolean isHeadsUp = (child instanceof ExpandableNotificationRow) && child.isPinned();
if (mClipNotificationScrollToTop if (mClipNotificationScrollToTop
&& (!state.inShelf || (isHeadsUp && !firstHeadsUp)) && ((isHeadsUp && !firstHeadsUp) || child.isHeadsUpAnimatingAway())
&& newYTranslation < clipStart && newNotificationEnd > firstHeadsUpEnd
&& !ambientState.isShadeExpanded()) { && !ambientState.isShadeExpanded()) {
// The previous view is overlapping on top, clip! // The bottom of this view is peeking out from under the previous view.
float overlapAmount = clipStart - newYTranslation; // Clip the part that is peeking out.
state.clipTopAmount = (int) overlapAmount; float overlapAmount = newNotificationEnd - firstHeadsUpEnd;
state.clipBottomAmount = (int) overlapAmount;
} else { } else {
state.clipTopAmount = 0; state.clipBottomAmount = 0;
}
if (firstHeadsUp) {
firstHeadsUpEnd = newNotificationEnd;
} }
if (isHeadsUp) { if (isHeadsUp) {
firstHeadsUp = false; firstHeadsUp = false;
@@ -635,8 +640,6 @@ public class StackScrollAlgorithm {
// Ensure that a headsUp doesn't vertically extend further than the heads-up at // Ensure that a headsUp doesn't vertically extend further than the heads-up at
// the top most z-position // the top most z-position
childState.height = row.getIntrinsicHeight(); childState.height = row.getIntrinsicHeight();
childState.yTranslation = Math.min(topState.yTranslation + topState.height
- childState.height, childState.yTranslation);
} }
// heads up notification show and this row is the top entry of heads up // heads up notification show and this row is the top entry of heads up