summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java25
1 files changed, 18 insertions, 7 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index fbe88dff07f1..7addc8fe7a15 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -24,6 +24,7 @@ import android.graphics.Canvas;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.MathUtils;
+import android.view.Choreographer;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityManager;
@@ -492,12 +493,9 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
if (animationListener != null) {
mAppearAnimator.addListener(animationListener);
}
- if (delay > 0) {
- // we need to apply the initial state already to avoid drawn frames in the wrong state
- updateAppearAnimationAlpha();
- updateAppearRect();
- mAppearAnimator.setStartDelay(delay);
- }
+ // we need to apply the initial state already to avoid drawn frames in the wrong state
+ updateAppearAnimationAlpha();
+ updateAppearRect();
mAppearAnimator.addListener(new AnimatorListenerAdapter() {
private boolean mWasCancelled;
@@ -528,7 +526,20 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
mWasCancelled = true;
}
});
- mAppearAnimator.start();
+
+ // Cache the original animator so we can check if the animation should be started in the
+ // Choreographer callback. It's possible that the original animator (mAppearAnimator) is
+ // replaced with a new value before the callback is called.
+ ValueAnimator cachedAnimator = mAppearAnimator;
+ // Even when delay=0, starting the animation on the next frame is necessary to avoid jank.
+ // Not doing so will increase the chances our Animator will be forced to skip a value of
+ // the animation's progression, causing stutter.
+ Choreographer.getInstance().postFrameCallbackDelayed(
+ frameTimeNanos -> {
+ if (mAppearAnimator == cachedAnimator) {
+ mAppearAnimator.start();
+ }
+ }, delay);
}
private int getCujType(boolean isAppearing) {