Merge "Tuned the heads up animations more" into sc-dev am: 157c57fda7

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

Change-Id: I311dcd7cce8d8ffd5b31307323b14528e58ac8bb
This commit is contained in:
Selim Cinek
2021-06-08 17:46:52 +00:00
committed by Automerger Merge Worker
7 changed files with 50 additions and 106 deletions

View File

@@ -60,12 +60,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
*/ */
private static final float HORIZONTAL_ANIMATION_END = 0.2f; private static final float HORIZONTAL_ANIMATION_END = 0.2f;
/**
* At which point from [0,1] does the alpha animation end (or start when
* expanding)? 1.0 meaning that it ends immediately and 0.0 that it is continuously animated.
*/
private static final float ALPHA_ANIMATION_END = 0.0f;
/** /**
* At which point from [0,1] does the horizontal collapse animation start (or start when * At which point from [0,1] does the horizontal collapse animation start (or start when
* expanding)? 1.0 meaning that it starts immediately and 0.0 that it is animated at all. * expanding)? 1.0 meaning that it starts immediately and 0.0 that it is animated at all.
@@ -497,10 +491,10 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
float targetValue; float targetValue;
if (isAppearing) { if (isAppearing) {
mCurrentAppearInterpolator = mSlowOutFastInInterpolator; mCurrentAppearInterpolator = Interpolators.FAST_OUT_SLOW_IN;
targetValue = 1.0f; targetValue = 1.0f;
} else { } else {
mCurrentAppearInterpolator = Interpolators.FAST_OUT_SLOW_IN; mCurrentAppearInterpolator = mSlowOutFastInInterpolator;
targetValue = 0.0f; targetValue = 0.0f;
} }
mAppearAnimator = ValueAnimator.ofFloat(mAppearAnimationFraction, mAppearAnimator = ValueAnimator.ofFloat(mAppearAnimationFraction,
@@ -584,19 +578,21 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
} }
private void updateAppearRect() { private void updateAppearRect() {
float inverseFraction = (1.0f - mAppearAnimationFraction); float interpolatedFraction = mCurrentAppearInterpolator.getInterpolation(
float translationFraction = mCurrentAppearInterpolator.getInterpolation(inverseFraction); mAppearAnimationFraction);
float translateYTotalAmount = translationFraction * mAnimationTranslationY; mAppearAnimationTranslation = (1.0f - interpolatedFraction) * mAnimationTranslationY;
mAppearAnimationTranslation = translateYTotalAmount;
final int actualHeight = getActualHeight(); final int actualHeight = getActualHeight();
float bottom = actualHeight * mAppearAnimationFraction; float bottom = actualHeight * interpolatedFraction;
setOutlineRect(0, mAppearAnimationTranslation, setOutlineRect(0, mAppearAnimationTranslation, getWidth(),
getWidth(), bottom + mAppearAnimationTranslation); bottom + mAppearAnimationTranslation);
} }
private float getAppearAnimationFraction() { private float getInterpolatedAppearAnimationFraction() {
return mAppearAnimationFraction >= 0 ? mAppearAnimationFraction : 1; if (mAppearAnimationFraction >= 0) {
return mCurrentAppearInterpolator.getInterpolation(mAppearAnimationFraction);
}
return 1.0f;
} }
private void updateAppearAnimationAlpha() { private void updateAppearAnimationAlpha() {
@@ -629,18 +625,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
@Override @Override
public float getCurrentBackgroundRadiusTop() { public float getCurrentBackgroundRadiusTop() {
float fraction = getAppearAnimationFraction(); float fraction = getInterpolatedAppearAnimationFraction();
return isHeadsUpAnimatingAway() || isHeadsUp() return MathUtils.lerp(0, super.getCurrentBackgroundRadiusTop(), fraction);
? mOutlineRadius * fraction
: super.getCurrentBackgroundRadiusTop();
} }
@Override @Override
public float getCurrentBackgroundRadiusBottom() { public float getCurrentBackgroundRadiusBottom() {
float fraction = getAppearAnimationFraction(); float fraction = getInterpolatedAppearAnimationFraction();
return isHeadsUpAnimatingAway() || isHeadsUp() return MathUtils.lerp(0, super.getCurrentBackgroundRadiusBottom(), fraction);
? mOutlineRadius * fraction
: super.getCurrentBackgroundRadiusBottom();
} }
private void applyBackgroundRoundness(float topRadius, float bottomRadius) { private void applyBackgroundRoundness(float topRadius, float bottomRadius) {

View File

@@ -249,9 +249,18 @@ public abstract class ExpandableOutlineView extends ExpandableView {
@Override @Override
public boolean setTopRoundness(float topRoundness, boolean animate) { public boolean setTopRoundness(float topRoundness, boolean animate) {
if (mTopRoundness != topRoundness) { if (mTopRoundness != topRoundness) {
float diff = Math.abs(topRoundness - mTopRoundness);
mTopRoundness = topRoundness; mTopRoundness = topRoundness;
boolean shouldAnimate = animate;
if (PropertyAnimator.isAnimating(this, TOP_ROUNDNESS) && diff > 0.5f) {
// Fail safe:
// when we've been animating previously and we're now getting an update in the
// other direction, make sure to animate it too, otherwise, the localized updating
// may make the start larger than 1.0.
shouldAnimate = true;
}
PropertyAnimator.setProperty(this, TOP_ROUNDNESS, topRoundness, PropertyAnimator.setProperty(this, TOP_ROUNDNESS, topRoundness,
ROUNDNESS_PROPERTIES, animate); ROUNDNESS_PROPERTIES, shouldAnimate);
return true; return true;
} }
return false; return false;
@@ -286,9 +295,18 @@ public abstract class ExpandableOutlineView extends ExpandableView {
@Override @Override
public boolean setBottomRoundness(float bottomRoundness, boolean animate) { public boolean setBottomRoundness(float bottomRoundness, boolean animate) {
if (mBottomRoundness != bottomRoundness) { if (mBottomRoundness != bottomRoundness) {
float diff = Math.abs(bottomRoundness - mBottomRoundness);
mBottomRoundness = bottomRoundness; mBottomRoundness = bottomRoundness;
boolean shouldAnimate = animate;
if (PropertyAnimator.isAnimating(this, BOTTOM_ROUNDNESS) && diff > 0.5f) {
// Fail safe:
// when we've been animating previously and we're now getting an update in the
// other direction, make sure to animate it too, otherwise, the localized updating
// may make the start larger than 1.0.
shouldAnimate = true;
}
PropertyAnimator.setProperty(this, BOTTOM_ROUNDNESS, bottomRoundness, PropertyAnimator.setProperty(this, BOTTOM_ROUNDNESS, bottomRoundness,
ROUNDNESS_PROPERTIES, animate); ROUNDNESS_PROPERTIES, shouldAnimate);
return true; return true;
} }
return false; return false;

View File

@@ -1,52 +0,0 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.systemui.statusbar.notification.stack;
import android.graphics.Path;
import android.view.animation.PathInterpolator;
/**
* An interpolator specifically designed for the appear animation of heads up notifications.
*/
public class HeadsUpAppearInterpolator extends PathInterpolator {
private static float X1 = 250f;
private static float X2 = 200f;
private static float XTOT = (X1 + X2);;
public HeadsUpAppearInterpolator() {
super(getAppearPath());
}
private static Path getAppearPath() {
Path path = new Path();
path.moveTo(0, 0);
float y1 = 90f;
float y2 = 80f;
path.cubicTo(X1 * 0.8f / XTOT, y1 / y2,
X1 * 0.8f / XTOT, y1 / y2,
X1 / XTOT, y1 / y2);
path.cubicTo((X1 + X2 * 0.4f) / XTOT, y1 / y2,
(X1 + X2 * 0.2f) / XTOT, 1.0f,
1.0f , 1.0f);
return path;
}
public static float getFractionUntilOvershoot() {
return X1 / XTOT;
}
}

View File

@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.notification.stack;
import android.content.res.Resources; import android.content.res.Resources;
import android.util.MathUtils; import android.util.MathUtils;
import android.view.View;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.SysUISingleton;
@@ -199,7 +198,7 @@ public class NotificationRoundnessManager {
mExpanded = expandedHeight != 0.0f; mExpanded = expandedHeight != 0.0f;
mAppearFraction = appearFraction; mAppearFraction = appearFraction;
if (mTrackedHeadsUp != null) { if (mTrackedHeadsUp != null) {
updateView(mTrackedHeadsUp, true); updateView(mTrackedHeadsUp, false /* animate */);
} }
} }

View File

@@ -548,7 +548,11 @@ public class NotificationStackScrollLayoutController {
@Override @Override
public void onHeadsUpUnPinned(NotificationEntry entry) { public void onHeadsUpUnPinned(NotificationEntry entry) {
mNotificationRoundnessManager.updateView(entry.getRow(), true /* animate */); ExpandableNotificationRow row = entry.getRow();
// update the roundedness posted, because we might be animating away the
// headsup soon, so no need to set the roundedness to 0 and then back to 1.
row.post(() -> mNotificationRoundnessManager.updateView(row,
true /* animate */));
} }
@Override @Override
@@ -557,7 +561,9 @@ public class NotificationStackScrollLayoutController {
NotificationEntry topEntry = mHeadsUpManager.getTopEntry(); NotificationEntry topEntry = mHeadsUpManager.getTopEntry();
mView.setNumHeadsUp(numEntries); mView.setNumHeadsUp(numEntries);
mView.setTopHeadsUpEntry(topEntry); mView.setTopHeadsUpEntry(topEntry);
mNotificationRoundnessManager.updateView(entry.getRow(), false /* animate */); generateHeadsUpAnimation(entry, isHeadsUp);
ExpandableNotificationRow row = entry.getRow();
mNotificationRoundnessManager.updateView(row, true /* animate */);
} }
}; };
@@ -1234,7 +1240,7 @@ public class NotificationStackScrollLayoutController {
return mView.getFirstChildNotGone(); return mView.getFirstChildNotGone();
} }
public void generateHeadsUpAnimation(NotificationEntry entry, boolean isHeadsUp) { private void generateHeadsUpAnimation(NotificationEntry entry, boolean isHeadsUp) {
mView.generateHeadsUpAnimation(entry, isHeadsUp); mView.generateHeadsUpAnimation(entry, isHeadsUp);
} }

View File

@@ -21,7 +21,6 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.util.Property; import android.util.Property;
import android.view.View; import android.view.View;
import android.view.animation.Interpolator;
import com.android.keyguard.KeyguardSliceView; import com.android.keyguard.KeyguardSliceView;
import com.android.systemui.R; import com.android.systemui.R;
@@ -50,11 +49,8 @@ public class StackStateAnimator {
public static final int ANIMATION_DURATION_SWIPE = 260; public static final int ANIMATION_DURATION_SWIPE = 260;
public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220; public static final int ANIMATION_DURATION_DIMMED_ACTIVATED = 220;
public static final int ANIMATION_DURATION_CLOSE_REMOTE_INPUT = 150; public static final int ANIMATION_DURATION_CLOSE_REMOTE_INPUT = 150;
public static final int ANIMATION_DURATION_HEADS_UP_APPEAR = 550; public static final int ANIMATION_DURATION_HEADS_UP_APPEAR = 400;
public static final int ANIMATION_DURATION_HEADS_UP_APPEAR_CLOSED public static final int ANIMATION_DURATION_HEADS_UP_DISAPPEAR = 400;
= (int) (ANIMATION_DURATION_HEADS_UP_APPEAR
* HeadsUpAppearInterpolator.getFractionUntilOvershoot());
public static final int ANIMATION_DURATION_HEADS_UP_DISAPPEAR = 300;
public static final int ANIMATION_DURATION_PULSE_APPEAR = public static final int ANIMATION_DURATION_PULSE_APPEAR =
KeyguardSliceView.DEFAULT_ANIM_DURATION; KeyguardSliceView.DEFAULT_ANIM_DURATION;
public static final int ANIMATION_DURATION_BLOCKING_HELPER_FADE = 240; public static final int ANIMATION_DURATION_BLOCKING_HELPER_FADE = 240;
@@ -64,8 +60,6 @@ public class StackStateAnimator {
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;
private static final int MAX_STAGGER_COUNT = 5; private static final int MAX_STAGGER_COUNT = 5;
private static final HeadsUpAppearInterpolator HEADS_UP_APPEAR_INTERPOLATOR =
new HeadsUpAppearInterpolator();
private final int mGoToFullShadeAppearingTranslation; private final int mGoToFullShadeAppearingTranslation;
private final int mPulsingAppearingTranslation; private final int mPulsingAppearingTranslation;
@@ -115,14 +109,6 @@ public class StackStateAnimator {
public boolean wasAdded(View view) { public boolean wasAdded(View view) {
return mNewAddChildren.contains(view); return mNewAddChildren.contains(view);
} }
@Override
public Interpolator getCustomInterpolator(View child, Property property) {
if (mHeadsUpAppearChildren.contains(child) && View.TRANSLATION_Y.equals(property)) {
return HEADS_UP_APPEAR_INTERPOLATOR;
}
return null;
}
}; };
} }
@@ -422,7 +408,7 @@ public class StackStateAnimator {
if (event.headsUpFromBottom) { if (event.headsUpFromBottom) {
mTmpState.yTranslation = mHeadsUpAppearHeightBottom; mTmpState.yTranslation = mHeadsUpAppearHeightBottom;
} else { } else {
changingView.performAddAnimation(0, ANIMATION_DURATION_HEADS_UP_APPEAR_CLOSED, changingView.performAddAnimation(0, ANIMATION_DURATION_HEADS_UP_APPEAR,
true /* isHeadsUpAppear */); true /* isHeadsUpAppear */);
} }
mHeadsUpAppearChildren.add(changingView); mHeadsUpAppearChildren.add(changingView);

View File

@@ -4153,11 +4153,6 @@ public class NotificationPanelViewController extends PanelViewController {
entry.setHeadsUpIsVisible(); entry.setHeadsUpIsVisible();
} }
} }
@Override
public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
mNotificationStackScrollLayoutController.generateHeadsUpAnimation(entry, isHeadsUp);
}
} }
private class HeightListener implements QS.HeightListener { private class HeightListener implements QS.HeightListener {