Loading packages/SystemUI/res/values/ids.xml +3 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ <item type="id" name="scale_x_animator_tag"/> <item type="id" name="scale_y_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="x_animator_tag"/> <item type="id" name="y_animator_tag"/> Loading @@ -33,6 +34,7 @@ <item type="id" name="scale_y_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="bottom_inset_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="y_animator_tag_end_value"/> Loading @@ -43,6 +45,7 @@ <item type="id" name="scale_y_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="bottom_inset_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="y_animator_tag_start_value"/> Loading packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +6 −9 Original line number Diff line number Diff line Loading @@ -594,17 +594,14 @@ public class NotificationShelf extends ActivatableNotificationView implements } else { shouldClipOwnTop = view.showingPulsing(); } if (viewEnd > notificationClipEnd && !shouldClipOwnTop && (mAmbientState.isShadeExpanded() || !isPinned)) { if (!isPinned) { if (viewEnd > notificationClipEnd && !shouldClipOwnTop) { int clipBottomAmount = (int) (viewEnd - notificationClipEnd); if (isPinned) { clipBottomAmount = Math.min(view.getIntrinsicHeight() - view.getCollapsedHeight(), clipBottomAmount); } view.setClipBottomAmount(clipBottomAmount); } else { view.setClipBottomAmount(0); } } if (shouldClipOwnTop) { return (int) (viewEnd - getTranslationY()); } else { Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java +56 −26 Original line number Diff line number Diff line Loading @@ -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_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_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_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. Loading Loading @@ -96,11 +99,16 @@ public class ExpandableViewState extends ViewState { public boolean headsUpIsVisible; /** * 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. * How much the child overlaps on top with the child above. */ 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 */ Loading Loading @@ -138,8 +146,8 @@ public class ExpandableViewState extends ViewState { if (view instanceof ExpandableView) { ExpandableView expandableView = (ExpandableView) view; int height = expandableView.getActualHeight(); int newHeight = this.height; final int height = expandableView.getActualHeight(); final int newHeight = this.height; // apply height if (height != newHeight) { Loading @@ -157,10 +165,14 @@ public class ExpandableViewState extends ViewState { expandableView.setBelowSpeedBump(this.belowSpeedBump); // apply clipping float oldClipTopAmount = expandableView.getClipTopAmount(); final float oldClipTopAmount = expandableView.getClipTopAmount(); if (oldClipTopAmount != this.clipTopAmount) { expandableView.setClipTopAmount(this.clipTopAmount); } final float oldClipBottomAmount = expandableView.getClipBottomAmount(); if (oldClipBottomAmount != this.clipBottomAmount) { expandableView.setClipBottomAmount(this.clipBottomAmount); } expandableView.setTransformingInShelf(false); expandableView.setInShelf(inShelf); Loading @@ -187,13 +199,20 @@ public class ExpandableViewState extends ViewState { abortAnimation(child, TAG_ANIMATOR_HEIGHT); } // start top inset animation // start clip top animation if (this.clipTopAmount != expandableView.getClipTopAmount()) { startInsetAnimation(expandableView, properties); startClipAnimation(expandableView, properties, /* clipTop */true); } else { 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 expandableView.setDimmed(this.dimmed, animationFilter.animateDimmed); Loading Loading @@ -301,16 +320,20 @@ public class ExpandableViewState extends ViewState { child.setActualHeightAnimating(true); } private void startInsetAnimation(final ExpandableView child, AnimationProperties properties) { Integer previousStartValue = getChildTag(child, TAG_START_TOP_INSET); Integer previousEndValue = getChildTag(child, TAG_END_TOP_INSET); int newEndValue = this.clipTopAmount; private void startClipAnimation(final ExpandableView child, AnimationProperties properties, boolean clipTop) { Integer previousStartValue = getChildTag(child, 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) { 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(); if (!filter.animateTopInset) { if (clipTop && !filter.animateTopInset || !clipTop) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the Loading @@ -319,22 +342,28 @@ public class ExpandableViewState extends ViewState { int relativeDiff = newEndValue - previousEndValue; int newStartValue = previousStartValue + relativeDiff; values[0].setIntValues(newStartValue, newEndValue); child.setTag(TAG_START_TOP_INSET, newStartValue); child.setTag(TAG_END_TOP_INSET, newEndValue); child.setTag(clipTop ? TAG_START_TOP_INSET : TAG_START_BOTTOM_INSET, newStartValue); child.setTag(clipTop ? TAG_END_TOP_INSET : TAG_END_BOTTOM_INSET, newEndValue); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); return; } else { // no new animation needed, let's just apply the value if (clipTop) { child.setClipTopAmount(newEndValue); } else { child.setClipBottomAmount(newEndValue); } return; } } ValueAnimator animator = ValueAnimator.ofInt(child.getClipTopAmount(), newEndValue); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { ValueAnimator animator = ValueAnimator.ofInt( clipTop ? child.getClipTopAmount() : child.getClipBottomAmount(), newEndValue); animator.addUpdateListener(animation -> { if (clipTop) { child.setClipTopAmount((int) animation.getAnimatedValue()); } else { child.setClipBottomAmount((int) animation.getAnimatedValue()); } }); animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); Loading @@ -353,15 +382,16 @@ public class ExpandableViewState extends ViewState { animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { child.setTag(TAG_ANIMATOR_TOP_INSET, null); child.setTag(TAG_START_TOP_INSET, null); child.setTag(TAG_END_TOP_INSET, null); child.setTag(clipTop ? TAG_ANIMATOR_TOP_INSET : TAG_ANIMATOR_BOTTOM_INSET, null); child.setTag(clipTop ? TAG_START_TOP_INSET : TAG_START_BOTTOM_INSET, null); child.setTag(clipTop ? TAG_END_TOP_INSET : TAG_END_BOTTOM_INSET, null); } }); startAnimator(animator, listener); child.setTag(TAG_ANIMATOR_TOP_INSET, animator); child.setTag(TAG_START_TOP_INSET, child.getClipTopAmount()); child.setTag(TAG_END_TOP_INSET, newEndValue); child.setTag(clipTop ? TAG_ANIMATOR_TOP_INSET:TAG_ANIMATOR_BOTTOM_INSET, animator); child.setTag(clipTop ? TAG_START_TOP_INSET: TAG_START_BOTTOM_INSET, clipTop ? child.getClipTopAmount() : child.getClipBottomAmount()); child.setTag(clipTop ? TAG_END_TOP_INSET: TAG_END_BOTTOM_INSET, newEndValue); } /** Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +11 −8 Original line number Diff line number Diff line Loading @@ -192,6 +192,7 @@ public class StackScrollAlgorithm { float clipStart = 0; int childCount = algorithmState.visibleChildren.size(); boolean firstHeadsUp = true; float firstHeadsUpEnd = 0; for (int i = 0; i < childCount; i++) { ExpandableView child = algorithmState.visibleChildren.get(i); ExpandableViewState state = child.getViewState(); Loading @@ -203,14 +204,18 @@ public class StackScrollAlgorithm { float newNotificationEnd = newYTranslation + newHeight; boolean isHeadsUp = (child instanceof ExpandableNotificationRow) && child.isPinned(); if (mClipNotificationScrollToTop && (!state.inShelf || (isHeadsUp && !firstHeadsUp)) && newYTranslation < clipStart && ((isHeadsUp && !firstHeadsUp) || child.isHeadsUpAnimatingAway()) && newNotificationEnd > firstHeadsUpEnd && !ambientState.isShadeExpanded()) { // The previous view is overlapping on top, clip! float overlapAmount = clipStart - newYTranslation; state.clipTopAmount = (int) overlapAmount; // The bottom of this view is peeking out from under the previous view. // Clip the part that is peeking out. float overlapAmount = newNotificationEnd - firstHeadsUpEnd; state.clipBottomAmount = (int) overlapAmount; } else { state.clipTopAmount = 0; state.clipBottomAmount = 0; } if (firstHeadsUp) { firstHeadsUpEnd = newNotificationEnd; } if (isHeadsUp) { firstHeadsUp = false; Loading Loading @@ -635,8 +640,6 @@ public class StackScrollAlgorithm { // Ensure that a headsUp doesn't vertically extend further than the heads-up at // the top most z-position 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 Loading Loading
packages/SystemUI/res/values/ids.xml +3 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ <item type="id" name="scale_x_animator_tag"/> <item type="id" name="scale_y_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="x_animator_tag"/> <item type="id" name="y_animator_tag"/> Loading @@ -33,6 +34,7 @@ <item type="id" name="scale_y_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="bottom_inset_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="y_animator_tag_end_value"/> Loading @@ -43,6 +45,7 @@ <item type="id" name="scale_y_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="bottom_inset_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="y_animator_tag_start_value"/> Loading
packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +6 −9 Original line number Diff line number Diff line Loading @@ -594,17 +594,14 @@ public class NotificationShelf extends ActivatableNotificationView implements } else { shouldClipOwnTop = view.showingPulsing(); } if (viewEnd > notificationClipEnd && !shouldClipOwnTop && (mAmbientState.isShadeExpanded() || !isPinned)) { if (!isPinned) { if (viewEnd > notificationClipEnd && !shouldClipOwnTop) { int clipBottomAmount = (int) (viewEnd - notificationClipEnd); if (isPinned) { clipBottomAmount = Math.min(view.getIntrinsicHeight() - view.getCollapsedHeight(), clipBottomAmount); } view.setClipBottomAmount(clipBottomAmount); } else { view.setClipBottomAmount(0); } } if (shouldClipOwnTop) { return (int) (viewEnd - getTranslationY()); } else { Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java +56 −26 Original line number Diff line number Diff line Loading @@ -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_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_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_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. Loading Loading @@ -96,11 +99,16 @@ public class ExpandableViewState extends ViewState { public boolean headsUpIsVisible; /** * 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. * How much the child overlaps on top with the child above. */ 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 */ Loading Loading @@ -138,8 +146,8 @@ public class ExpandableViewState extends ViewState { if (view instanceof ExpandableView) { ExpandableView expandableView = (ExpandableView) view; int height = expandableView.getActualHeight(); int newHeight = this.height; final int height = expandableView.getActualHeight(); final int newHeight = this.height; // apply height if (height != newHeight) { Loading @@ -157,10 +165,14 @@ public class ExpandableViewState extends ViewState { expandableView.setBelowSpeedBump(this.belowSpeedBump); // apply clipping float oldClipTopAmount = expandableView.getClipTopAmount(); final float oldClipTopAmount = expandableView.getClipTopAmount(); if (oldClipTopAmount != this.clipTopAmount) { expandableView.setClipTopAmount(this.clipTopAmount); } final float oldClipBottomAmount = expandableView.getClipBottomAmount(); if (oldClipBottomAmount != this.clipBottomAmount) { expandableView.setClipBottomAmount(this.clipBottomAmount); } expandableView.setTransformingInShelf(false); expandableView.setInShelf(inShelf); Loading @@ -187,13 +199,20 @@ public class ExpandableViewState extends ViewState { abortAnimation(child, TAG_ANIMATOR_HEIGHT); } // start top inset animation // start clip top animation if (this.clipTopAmount != expandableView.getClipTopAmount()) { startInsetAnimation(expandableView, properties); startClipAnimation(expandableView, properties, /* clipTop */true); } else { 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 expandableView.setDimmed(this.dimmed, animationFilter.animateDimmed); Loading Loading @@ -301,16 +320,20 @@ public class ExpandableViewState extends ViewState { child.setActualHeightAnimating(true); } private void startInsetAnimation(final ExpandableView child, AnimationProperties properties) { Integer previousStartValue = getChildTag(child, TAG_START_TOP_INSET); Integer previousEndValue = getChildTag(child, TAG_END_TOP_INSET); int newEndValue = this.clipTopAmount; private void startClipAnimation(final ExpandableView child, AnimationProperties properties, boolean clipTop) { Integer previousStartValue = getChildTag(child, 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) { 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(); if (!filter.animateTopInset) { if (clipTop && !filter.animateTopInset || !clipTop) { // just a local update was performed if (previousAnimator != null) { // we need to increase all animation keyframes of the previous animator by the Loading @@ -319,22 +342,28 @@ public class ExpandableViewState extends ViewState { int relativeDiff = newEndValue - previousEndValue; int newStartValue = previousStartValue + relativeDiff; values[0].setIntValues(newStartValue, newEndValue); child.setTag(TAG_START_TOP_INSET, newStartValue); child.setTag(TAG_END_TOP_INSET, newEndValue); child.setTag(clipTop ? TAG_START_TOP_INSET : TAG_START_BOTTOM_INSET, newStartValue); child.setTag(clipTop ? TAG_END_TOP_INSET : TAG_END_BOTTOM_INSET, newEndValue); previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime()); return; } else { // no new animation needed, let's just apply the value if (clipTop) { child.setClipTopAmount(newEndValue); } else { child.setClipBottomAmount(newEndValue); } return; } } ValueAnimator animator = ValueAnimator.ofInt(child.getClipTopAmount(), newEndValue); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { ValueAnimator animator = ValueAnimator.ofInt( clipTop ? child.getClipTopAmount() : child.getClipBottomAmount(), newEndValue); animator.addUpdateListener(animation -> { if (clipTop) { child.setClipTopAmount((int) animation.getAnimatedValue()); } else { child.setClipBottomAmount((int) animation.getAnimatedValue()); } }); animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); Loading @@ -353,15 +382,16 @@ public class ExpandableViewState extends ViewState { animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { child.setTag(TAG_ANIMATOR_TOP_INSET, null); child.setTag(TAG_START_TOP_INSET, null); child.setTag(TAG_END_TOP_INSET, null); child.setTag(clipTop ? TAG_ANIMATOR_TOP_INSET : TAG_ANIMATOR_BOTTOM_INSET, null); child.setTag(clipTop ? TAG_START_TOP_INSET : TAG_START_BOTTOM_INSET, null); child.setTag(clipTop ? TAG_END_TOP_INSET : TAG_END_BOTTOM_INSET, null); } }); startAnimator(animator, listener); child.setTag(TAG_ANIMATOR_TOP_INSET, animator); child.setTag(TAG_START_TOP_INSET, child.getClipTopAmount()); child.setTag(TAG_END_TOP_INSET, newEndValue); child.setTag(clipTop ? TAG_ANIMATOR_TOP_INSET:TAG_ANIMATOR_BOTTOM_INSET, animator); child.setTag(clipTop ? TAG_START_TOP_INSET: TAG_START_BOTTOM_INSET, clipTop ? child.getClipTopAmount() : child.getClipBottomAmount()); child.setTag(clipTop ? TAG_END_TOP_INSET: TAG_END_BOTTOM_INSET, newEndValue); } /** Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java +11 −8 Original line number Diff line number Diff line Loading @@ -192,6 +192,7 @@ public class StackScrollAlgorithm { float clipStart = 0; int childCount = algorithmState.visibleChildren.size(); boolean firstHeadsUp = true; float firstHeadsUpEnd = 0; for (int i = 0; i < childCount; i++) { ExpandableView child = algorithmState.visibleChildren.get(i); ExpandableViewState state = child.getViewState(); Loading @@ -203,14 +204,18 @@ public class StackScrollAlgorithm { float newNotificationEnd = newYTranslation + newHeight; boolean isHeadsUp = (child instanceof ExpandableNotificationRow) && child.isPinned(); if (mClipNotificationScrollToTop && (!state.inShelf || (isHeadsUp && !firstHeadsUp)) && newYTranslation < clipStart && ((isHeadsUp && !firstHeadsUp) || child.isHeadsUpAnimatingAway()) && newNotificationEnd > firstHeadsUpEnd && !ambientState.isShadeExpanded()) { // The previous view is overlapping on top, clip! float overlapAmount = clipStart - newYTranslation; state.clipTopAmount = (int) overlapAmount; // The bottom of this view is peeking out from under the previous view. // Clip the part that is peeking out. float overlapAmount = newNotificationEnd - firstHeadsUpEnd; state.clipBottomAmount = (int) overlapAmount; } else { state.clipTopAmount = 0; state.clipBottomAmount = 0; } if (firstHeadsUp) { firstHeadsUpEnd = newNotificationEnd; } if (isHeadsUp) { firstHeadsUp = false; Loading Loading @@ -635,8 +640,6 @@ public class StackScrollAlgorithm { // Ensure that a headsUp doesn't vertically extend further than the heads-up at // the top most z-position 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 Loading