Fade in notifications one by one

NSSL#applyCurrentState sets ExpandableViewState#shouldFadeForShadeOpen
which ViewState uses to determine whether to animate alpha.

Bug: 172289889
Test: visual

Change-Id: Iab095bdbdbe6c3d882c0a8a0f678a132cdb6eaed
This commit is contained in:
Lyn Han
2021-01-19 21:32:02 -06:00
parent 195d1b15a6
commit 129869eb48
6 changed files with 60 additions and 25 deletions

View File

@@ -614,6 +614,12 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
}
}
public void setShouldFadeForShadeOpen(boolean shouldFade) {
if (!mViewState.gone) {
mViewState.setShouldFadeForShadeOpen(shouldFade);
}
}
/**
* @return whether the current view doesn't add height to the overall content. This means that
* if it is added to a list of items, its content will still have the same height.

View File

@@ -88,6 +88,12 @@ public class ExpandableViewState extends ViewState {
public boolean hideSensitive;
public boolean belowSpeedBump;
public boolean inShelf;
public boolean shouldFadeForShadeOpen;
@Override
boolean shouldAnimateAlpha() {
return shouldFadeForShadeOpen;
}
/**
* A state indicating whether a headsup is currently fully visible, even when not scrolled.
@@ -171,6 +177,10 @@ public class ExpandableViewState extends ViewState {
}
}
public void setShouldFadeForShadeOpen(boolean shouldFade) {
shouldFadeForShadeOpen = shouldFade;
}
@Override
public void animateTo(View child, AnimationProperties properties) {
super.animateTo(child, properties);

View File

@@ -3947,6 +3947,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
int numChildren = getChildCount();
for (int i = 0; i < numChildren; i++) {
ExpandableView child = (ExpandableView) getChildAt(i);
child.setShouldFadeForShadeOpen(mAmbientState.isShadeOpening());
child.applyViewState();
}

View File

@@ -568,11 +568,14 @@ public class StackScrollAlgorithm {
// Add padding before sections for overscroll effect.
childViewState.yTranslation += ambientState.getSectionPadding();
}
if (childViewState.yTranslation >= shelfStart) {
childViewState.hidden = !child.isExpandAnimationRunning() && !child.hasExpandingChild();
childViewState.inShelf = true;
childViewState.headsUpIsVisible = false;
}
boolean show = childViewState.yTranslation < shelfStart
&& !ambientState.isAppearing();
childViewState.hidden = !show
&& !child.isExpandAnimationRunning()
&& !child.hasExpandingChild();
childViewState.inShelf = !show;
childViewState.headsUpIsVisible = show;
childViewState.alpha = show ? 1f : 0f;
}
protected int getMaxAllowedChildHeight(View child) {

View File

@@ -45,6 +45,7 @@ public class StackStateAnimator {
public static final int ANIMATION_DURATION_CORNER_RADIUS = 200;
public static final int ANIMATION_DURATION_WAKEUP = 500;
public static final int ANIMATION_DURATION_GO_TO_FULL_SHADE = 448;
public static final int ANIMATION_DURATION_FADE_IN = 700;
public static final int ANIMATION_DURATION_APPEAR_DISAPPEAR = 464;
public static final int ANIMATION_DURATION_SWIPE = 260;
public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220;

View File

@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.stack;
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_FADE_IN;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
@@ -56,6 +58,16 @@ public class ViewState implements Dumpable {
return mAnimationFilter;
}
};
protected static final AnimationProperties ANIMATE_ALPHA = new AnimationProperties() {
AnimationFilter mAnimationFilter = new AnimationFilter();
@Override
public AnimationFilter getAnimationFilter() {
mAnimationFilter.animateAlpha();
return mAnimationFilter;
}
}.setDuration(ANIMATION_DURATION_FADE_IN);
private static final int TAG_ANIMATOR_TRANSLATION_X = R.id.translation_x_animator_tag;
private static final int TAG_ANIMATOR_TRANSLATION_Y = R.id.translation_y_animator_tag;
private static final int TAG_ANIMATOR_TRANSLATION_Z = R.id.translation_z_animator_tag;
@@ -148,6 +160,10 @@ public class ViewState implements Dumpable {
scaleY = view.getScaleY();
}
boolean shouldAnimateAlpha() {
return false;
}
/**
* Applies a {@link ViewState} to a normal view.
*/
@@ -200,24 +216,26 @@ public class ViewState implements Dumpable {
int oldVisibility = view.getVisibility();
boolean becomesInvisible = this.alpha == 0.0f
|| (this.hidden && (!isAnimating(view) || oldVisibility != View.VISIBLE));
boolean animatingAlpha = isAnimating(view, TAG_ANIMATOR_ALPHA);
if (animatingAlpha) {
updateAlphaAnimation(view);
if (isAnimating(view, TAG_ANIMATOR_ALPHA)) {
startAlphaAnimation(view, NO_NEW_ANIMATIONS);
} else if (view.getAlpha() != this.alpha) {
// apply layer type
boolean becomesFullyVisible = this.alpha == 1.0f;
boolean newLayerTypeIsHardware = !becomesInvisible && !becomesFullyVisible
&& view.hasOverlappingRendering();
int layerType = view.getLayerType();
int newLayerType = newLayerTypeIsHardware
? View.LAYER_TYPE_HARDWARE
: View.LAYER_TYPE_NONE;
if (layerType != newLayerType) {
view.setLayerType(newLayerType, null);
if (shouldAnimateAlpha()) {
startAlphaAnimation(view, ANIMATE_ALPHA);
} else {
// apply layer type
boolean becomesFullyVisible = this.alpha == 1.0f;
boolean newLayerTypeIsHardware = !becomesInvisible && !becomesFullyVisible
&& view.hasOverlappingRendering();
int layerType = view.getLayerType();
int newLayerType = newLayerTypeIsHardware
? View.LAYER_TYPE_HARDWARE
: View.LAYER_TYPE_NONE;
if (layerType != newLayerType) {
view.setLayerType(newLayerType, null);
}
// apply alpha
view.setAlpha(this.alpha);
}
// apply alpha
view.setAlpha(this.alpha);
}
// apply visibility
@@ -322,10 +340,6 @@ public class ViewState implements Dumpable {
}
}
private void updateAlphaAnimation(View view) {
startAlphaAnimation(view, NO_NEW_ANIMATIONS);
}
private void startAlphaAnimation(final View child, AnimationProperties properties) {
Float previousStartValue = getChildTag(child,TAG_START_ALPHA);
Float previousEndValue = getChildTag(child,TAG_END_ALPHA);