Merge "Animation reveal animation for HUN and Shelf" into sc-dev

This commit is contained in:
Selim Cinek
2021-06-07 09:56:48 +00:00
committed by Android (Google) Code Review
6 changed files with 46 additions and 113 deletions

View File

@@ -20,14 +20,11 @@ import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.SystemProperties;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.MathUtils; import android.util.MathUtils;
import android.view.DisplayCutout;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
@@ -666,8 +663,8 @@ public class NotificationShelf extends ActivatableNotificationView implements
boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf(); boolean isAppearing = row.isDrawingAppearAnimation() && !row.isInShelf();
iconState.hidden = isAppearing iconState.hidden = isAppearing
|| (view instanceof ExpandableNotificationRow || (view instanceof ExpandableNotificationRow
&& ((ExpandableNotificationRow) view).isLowPriority() && ((ExpandableNotificationRow) view).isLowPriority()
&& mShelfIcons.hasMaxNumDot()) && mShelfIcons.hasMaxNumDot())
|| (transitionAmount == 0.0f && !iconState.isAnimating(icon)) || (transitionAmount == 0.0f && !iconState.isAnimating(icon))
|| row.isAboveShelf() || row.isAboveShelf()
|| row.showingPulsing() || row.showingPulsing()

View File

@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.notification.row;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
@@ -84,7 +83,16 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
* or {@link #setOverrideTintColor(int, float)}. * or {@link #setOverrideTintColor(int, float)}.
*/ */
protected static final int NO_COLOR = 0; protected static final int NO_COLOR = 0;
/**
* The content of the view should start showing at animation progress value of
* #ALPHA_APPEAR_START_FRACTION.
*/
private static final float ALPHA_APPEAR_START_FRACTION = .4f;
/**
* The content should show fully with progress at #ALPHA_APPEAR_END_FRACTION
* The start of the animation is at #ALPHA_APPEAR_START_FRACTION
*/
private static final float ALPHA_APPEAR_END_FRACTION = 1;
private static final Interpolator ACTIVATE_INVERSE_INTERPOLATOR private static final Interpolator ACTIVATE_INVERSE_INTERPOLATOR
= new PathInterpolator(0.6f, 0, 0.5f, 1); = new PathInterpolator(0.6f, 0, 0.5f, 1);
private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR
@@ -106,10 +114,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
private final Interpolator mSlowOutFastInInterpolator; private final Interpolator mSlowOutFastInInterpolator;
private final Interpolator mSlowOutLinearInInterpolator; private final Interpolator mSlowOutLinearInInterpolator;
private Interpolator mCurrentAppearInterpolator; private Interpolator mCurrentAppearInterpolator;
private Interpolator mCurrentAlphaInterpolator;
NotificationBackgroundView mBackgroundNormal; NotificationBackgroundView mBackgroundNormal;
private ObjectAnimator mBackgroundAnimator;
private RectF mAppearAnimationRect = new RectF(); private RectF mAppearAnimationRect = new RectF();
private float mAnimationTranslationY; private float mAnimationTranslationY;
private boolean mDrawingAppearAnimation; private boolean mDrawingAppearAnimation;
@@ -475,8 +481,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
private void startAppearAnimation(boolean isAppearing, float translationDirection, long delay, private void startAppearAnimation(boolean isAppearing, float translationDirection, long delay,
long duration, final Runnable onFinishedRunnable, long duration, final Runnable onFinishedRunnable,
AnimatorListenerAdapter animationListener) { AnimatorListenerAdapter animationListener) {
cancelAppearAnimation();
mAnimationTranslationY = translationDirection * getActualHeight(); mAnimationTranslationY = translationDirection * getActualHeight();
cancelAppearAnimation();
if (mAppearAnimationFraction == -1.0f) { if (mAppearAnimationFraction == -1.0f) {
// not initialized yet, we start anew // not initialized yet, we start anew
if (isAppearing) { if (isAppearing) {
@@ -492,15 +498,9 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
float targetValue; float targetValue;
if (isAppearing) { if (isAppearing) {
mCurrentAppearInterpolator = mSlowOutFastInInterpolator; mCurrentAppearInterpolator = mSlowOutFastInInterpolator;
mCurrentAlphaInterpolator = Interpolators.LINEAR_OUT_SLOW_IN;
targetValue = 1.0f; targetValue = 1.0f;
if (!mIsHeadsUpAnimation && isChildInGroup()) {
// slower fade in of children to avoid visibly overlapping with other children
mCurrentAlphaInterpolator = Interpolators.SLOW_OUT_LINEAR_IN;
}
} else { } else {
mCurrentAppearInterpolator = Interpolators.FAST_OUT_SLOW_IN; mCurrentAppearInterpolator = Interpolators.FAST_OUT_SLOW_IN;
mCurrentAlphaInterpolator = mSlowOutLinearInInterpolator;
targetValue = 0.0f; targetValue = 0.0f;
} }
mAppearAnimator = ValueAnimator.ofFloat(mAppearAnimationFraction, mAppearAnimator = ValueAnimator.ofFloat(mAppearAnimationFraction,
@@ -588,61 +588,23 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
float translationFraction = mCurrentAppearInterpolator.getInterpolation(inverseFraction); float translationFraction = mCurrentAppearInterpolator.getInterpolation(inverseFraction);
float translateYTotalAmount = translationFraction * mAnimationTranslationY; float translateYTotalAmount = translationFraction * mAnimationTranslationY;
mAppearAnimationTranslation = translateYTotalAmount; mAppearAnimationTranslation = translateYTotalAmount;
// handle width animation
float widthFraction = (inverseFraction - (1.0f - HORIZONTAL_ANIMATION_START))
/ (HORIZONTAL_ANIMATION_START - HORIZONTAL_ANIMATION_END);
widthFraction = Math.min(1.0f, Math.max(0.0f, widthFraction));
widthFraction = mCurrentAppearInterpolator.getInterpolation(widthFraction);
float startWidthFraction = HORIZONTAL_COLLAPSED_REST_PARTIAL;
if (mIsHeadsUpAnimation && !mIsAppearing) {
startWidthFraction = 0;
}
if (mIsAppearing && !mIsHeadsUpAnimation && isChildInGroup()) {
// Children in a group (when not heads up) should simply fade in.
startWidthFraction = 1;
}
float width = MathUtils.lerp(startWidthFraction, 1.0f, 1.0f - widthFraction)
* getWidth();
float left;
float right;
if (mIsHeadsUpAnimation) {
left = MathUtils.lerp(mHeadsUpLocation, 0, 1.0f - widthFraction);
right = left + width;
} else {
left = getWidth() * 0.5f - width / 2.0f;
right = getWidth() - left;
}
// handle top animation
float heightFraction = (inverseFraction - (1.0f - VERTICAL_ANIMATION_START)) /
VERTICAL_ANIMATION_START;
heightFraction = Math.max(0.0f, heightFraction);
heightFraction = mCurrentAppearInterpolator.getInterpolation(heightFraction);
float top;
float bottom;
final int actualHeight = getActualHeight(); final int actualHeight = getActualHeight();
if (mAnimationTranslationY > 0.0f) { float bottom = actualHeight * mAppearAnimationFraction;
bottom = actualHeight - heightFraction * mAnimationTranslationY * 0.1f
- translateYTotalAmount; setOutlineRect(0, mAppearAnimationTranslation,
top = bottom * heightFraction; getWidth(), bottom + mAppearAnimationTranslation);
} else { }
top = heightFraction * (actualHeight + mAnimationTranslationY) * 0.1f -
translateYTotalAmount; private float getAppearAnimationFraction() {
bottom = actualHeight * (1 - heightFraction) + top * heightFraction; return mAppearAnimationFraction >= 0 ? mAppearAnimationFraction : 1;
}
mAppearAnimationRect.set(left, top, right, bottom);
setOutlineRect(left, top + mAppearAnimationTranslation, right,
bottom + mAppearAnimationTranslation);
} }
private void updateAppearAnimationAlpha() { private void updateAppearAnimationAlpha() {
float contentAlphaProgress = mAppearAnimationFraction; float contentAlphaProgress = MathUtils.constrain(mAppearAnimationFraction,
contentAlphaProgress = contentAlphaProgress / (1.0f - ALPHA_ANIMATION_END); ALPHA_APPEAR_START_FRACTION, ALPHA_APPEAR_END_FRACTION);
contentAlphaProgress = Math.min(1.0f, contentAlphaProgress); float range = ALPHA_APPEAR_END_FRACTION - ALPHA_APPEAR_START_FRACTION;
contentAlphaProgress = mCurrentAlphaInterpolator.getInterpolation(contentAlphaProgress); float alpha = (contentAlphaProgress - ALPHA_APPEAR_START_FRACTION) / range;
setContentAlpha(contentAlphaProgress); setContentAlpha(Interpolators.ALPHA_IN.getInterpolation(alpha));
} }
private void setContentAlpha(float contentAlpha) { private void setContentAlpha(float contentAlpha) {
@@ -665,6 +627,22 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
getCurrentBackgroundRadiusBottom()); getCurrentBackgroundRadiusBottom());
} }
@Override
public float getCurrentBackgroundRadiusTop() {
float fraction = getAppearAnimationFraction();
return isHeadsUpAnimatingAway() || isHeadsUp()
? mOutlineRadius * fraction
: super.getCurrentBackgroundRadiusTop();
}
@Override
public float getCurrentBackgroundRadiusBottom() {
float fraction = getAppearAnimationFraction();
return isHeadsUpAnimatingAway() || isHeadsUp()
? mOutlineRadius * fraction
: super.getCurrentBackgroundRadiusBottom();
}
private void applyBackgroundRoundness(float topRadius, float bottomRadius) { private void applyBackgroundRoundness(float topRadius, float bottomRadius) {
mBackgroundNormal.setRadius(topRadius, bottomRadius); mBackgroundNormal.setRadius(topRadius, bottomRadius);
} }

View File

@@ -1997,23 +1997,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return false; return false;
} }
@Override
public float getCurrentTopRoundness() {
if (mExpandAnimationRunning) {
return mTopRoundnessDuringExpandAnimation;
}
return super.getCurrentTopRoundness();
}
@Override
public float getCurrentBottomRoundness() {
if (mExpandAnimationRunning) {
return mBottomRoundnessDuringExpandAnimation;
}
return super.getCurrentBottomRoundness();
}
public void applyExpandAnimationParams(ExpandAnimationParameters params) { public void applyExpandAnimationParams(ExpandAnimationParameters params) {
if (params == null) { if (params == null) {

View File

@@ -117,16 +117,6 @@ public class AnimationFilter {
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_GO_TO_FULL_SHADE) { NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_GO_TO_FULL_SHADE) {
hasGoToFullShadeEvent = true; hasGoToFullShadeEvent = true;
} }
if (ev.animationType == NotificationStackScrollLayout.AnimationEvent
.ANIMATION_TYPE_HEADS_UP_DISAPPEAR) {
customDelay = StackStateAnimator.ANIMATION_DELAY_HEADS_UP;
} else if (ev.animationType == NotificationStackScrollLayout.AnimationEvent
.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) {
// We need both timeouts when clicking, one to delay it and one for the animation
// to look nice
customDelay = StackStateAnimator.ANIMATION_DELAY_HEADS_UP_CLICKED
+ StackStateAnimator.ANIMATION_DELAY_HEADS_UP;
}
} }
} }

View File

@@ -538,7 +538,7 @@ public class StackScrollAlgorithm {
continue; continue;
} }
ExpandableNotificationRow row = (ExpandableNotificationRow) child; ExpandableNotificationRow row = (ExpandableNotificationRow) child;
if (!row.isHeadsUp()) { if (!(row.isHeadsUp() || row.isHeadsUpAnimatingAway())) {
continue; continue;
} }
ExpandableViewState childState = row.getViewState(); ExpandableViewState childState = row.getViewState();
@@ -585,6 +585,7 @@ public class StackScrollAlgorithm {
} }
} }
if (row.isHeadsUpAnimatingAway()) { if (row.isHeadsUpAnimatingAway()) {
childState.yTranslation = Math.max(childState.yTranslation, mHeadsUpInset);
childState.hidden = false; childState.hidden = false;
} }
} }

View File

@@ -63,8 +63,6 @@ public class StackStateAnimator {
public static final int ANIMATION_DELAY_PER_ELEMENT_MANUAL = 32; public static final int ANIMATION_DELAY_PER_ELEMENT_MANUAL = 32;
public static final int ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE = 48; public static final int ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE = 48;
public static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE = 2; public static final int DELAY_EFFECT_MAX_INDEX_DIFFERENCE = 2;
public static final int ANIMATION_DELAY_HEADS_UP = 120;
public static final int ANIMATION_DELAY_HEADS_UP_CLICKED= 120;
private static final int MAX_STAGGER_COUNT = 5; private static final int MAX_STAGGER_COUNT = 5;
private static final HeadsUpAppearInterpolator HEADS_UP_APPEAR_INTERPOLATOR = private static final HeadsUpAppearInterpolator HEADS_UP_APPEAR_INTERPOLATOR =
new HeadsUpAppearInterpolator(); new HeadsUpAppearInterpolator();
@@ -424,7 +422,6 @@ public class StackStateAnimator {
if (event.headsUpFromBottom) { if (event.headsUpFromBottom) {
mTmpState.yTranslation = mHeadsUpAppearHeightBottom; mTmpState.yTranslation = mHeadsUpAppearHeightBottom;
} else { } else {
mTmpState.yTranslation = 0;
changingView.performAddAnimation(0, ANIMATION_DURATION_HEADS_UP_APPEAR_CLOSED, changingView.performAddAnimation(0, ANIMATION_DURATION_HEADS_UP_APPEAR_CLOSED,
true /* isHeadsUpAppear */); true /* isHeadsUpAppear */);
} }
@@ -436,24 +433,11 @@ public class StackStateAnimator {
.AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) { .AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK) {
mHeadsUpDisappearChildren.add(changingView); mHeadsUpDisappearChildren.add(changingView);
Runnable endRunnable = null; Runnable endRunnable = null;
// We need some additional delay in case we were removed to make sure we're not
// lagging
int extraDelay = event.animationType == NotificationStackScrollLayout
.AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
? ANIMATION_DELAY_HEADS_UP_CLICKED
: 0;
if (changingView.getParent() == null) { if (changingView.getParent() == null) {
// This notification was actually removed, so we need to add it transiently // This notification was actually removed, so we need to add it transiently
mHostLayout.addTransientView(changingView, 0); mHostLayout.addTransientView(changingView, 0);
changingView.setTransientContainer(mHostLayout); changingView.setTransientContainer(mHostLayout);
mTmpState.initFrom(changingView); mTmpState.initFrom(changingView);
mTmpState.yTranslation = 0;
// We temporarily enable Y animations, the real filter will be combined
// afterwards anyway
mAnimationFilter.animateY = true;
mAnimationProperties.delay = extraDelay + ANIMATION_DELAY_HEADS_UP;
mAnimationProperties.duration = ANIMATION_DURATION_HEADS_UP_DISAPPEAR;
mTmpState.animateTo(changingView, mAnimationProperties);
endRunnable = () -> removeTransientView(changingView); endRunnable = () -> removeTransientView(changingView);
} }
float targetLocation = 0; float targetLocation = 0;
@@ -483,8 +467,8 @@ public class StackStateAnimator {
// running anymore, the panel will instantly hide itself. We need to wait until // running anymore, the panel will instantly hide itself. We need to wait until
// the animation is fully finished for this though. // the animation is fully finished for this though.
long removeAnimationDelay = changingView.performRemoveAnimation( long removeAnimationDelay = changingView.performRemoveAnimation(
ANIMATION_DURATION_HEADS_UP_DISAPPEAR + ANIMATION_DELAY_HEADS_UP, ANIMATION_DURATION_HEADS_UP_DISAPPEAR,
extraDelay, 0.0f, true /* isHeadsUpAppear */, targetLocation, 0, 0.0f, true /* isHeadsUpAppear */, targetLocation,
endRunnable, getGlobalAnimationFinishedListener()); endRunnable, getGlobalAnimationFinishedListener());
mAnimationProperties.delay += removeAnimationDelay; mAnimationProperties.delay += removeAnimationDelay;
} else if (endRunnable != null) { } else if (endRunnable != null) {