Adjust clock switch animation timing

Bug: 276236565
Test: Manually checked both clock switch animations on device
Change-Id: I1799bfd351ba9da61d9233f7a924145579758ee0
This commit is contained in:
Hawkwood Glazier
2023-05-01 18:18:08 +00:00
parent cdb792cf08
commit 5f3c9eab6c
4 changed files with 45 additions and 30 deletions

View File

@@ -272,6 +272,7 @@ class AnimatableClockView @JvmOverloads constructor(
color = lockScreenColor, color = lockScreenColor,
animate = isAnimationEnabled, animate = isAnimationEnabled,
duration = APPEAR_ANIM_DURATION, duration = APPEAR_ANIM_DURATION,
interpolator = Interpolators.EMPHASIZED_DECELERATE,
delay = 0, delay = 0,
onAnimationEnd = null onAnimationEnd = null
) )
@@ -562,7 +563,7 @@ class AnimatableClockView @JvmOverloads constructor(
private const val DOUBLE_LINE_FORMAT_12_HOUR = "hh\nmm" private const val DOUBLE_LINE_FORMAT_12_HOUR = "hh\nmm"
private const val DOUBLE_LINE_FORMAT_24_HOUR = "HH\nmm" private const val DOUBLE_LINE_FORMAT_24_HOUR = "HH\nmm"
private const val DOZE_ANIM_DURATION: Long = 300 private const val DOZE_ANIM_DURATION: Long = 300
private const val APPEAR_ANIM_DURATION: Long = 350 private const val APPEAR_ANIM_DURATION: Long = 833
private const val CHARGE_ANIM_DURATION_PHASE_0: Long = 500 private const val CHARGE_ANIM_DURATION_PHASE_0: Long = 500
private const val CHARGE_ANIM_DURATION_PHASE_1: Long = 1000 private const val CHARGE_ANIM_DURATION_PHASE_1: Long = 1000
private const val COLOR_ANIM_DURATION: Long = 400 private const val COLOR_ANIM_DURATION: Long = 400

View File

@@ -716,7 +716,7 @@
<!-- Minimum margin between clock and status bar --> <!-- Minimum margin between clock and status bar -->
<dimen name="keyguard_clock_top_margin">18dp</dimen> <dimen name="keyguard_clock_top_margin">18dp</dimen>
<!-- The amount to shift the clocks during a small/large transition --> <!-- The amount to shift the clocks during a small/large transition -->
<dimen name="keyguard_clock_switch_y_shift">10dp</dimen> <dimen name="keyguard_clock_switch_y_shift">14dp</dimen>
<!-- When large clock is showing, offset the smartspace by this amount --> <!-- When large clock is showing, offset the smartspace by this amount -->
<dimen name="keyguard_smartspace_top_offset">12dp</dimen> <dimen name="keyguard_smartspace_top_offset">12dp</dimen>
<!-- With the large clock, move up slightly from the center --> <!-- With the large clock, move up slightly from the center -->

View File

@@ -1,5 +1,8 @@
package com.android.keyguard; package com.android.keyguard;
import static android.view.View.ALPHA;
import static android.view.View.TRANSLATION_Y;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet; import android.animation.AnimatorSet;
@@ -35,11 +38,12 @@ public class KeyguardClockSwitch extends RelativeLayout {
private static final String TAG = "KeyguardClockSwitch"; private static final String TAG = "KeyguardClockSwitch";
private static final long CLOCK_OUT_MILLIS = 150; private static final long CLOCK_OUT_MILLIS = 133;
private static final long CLOCK_IN_MILLIS = 200; private static final long CLOCK_IN_MILLIS = 167;
public static final long CLOCK_IN_START_DELAY_MILLIS = CLOCK_OUT_MILLIS / 2; public static final long CLOCK_IN_START_DELAY_MILLIS = 133;
private static final long STATUS_AREA_START_DELAY_MILLIS = 50; private static final long STATUS_AREA_START_DELAY_MILLIS = 0;
private static final long STATUS_AREA_MOVE_MILLIS = 350; private static final long STATUS_AREA_MOVE_UP_MILLIS = 967;
private static final long STATUS_AREA_MOVE_DOWN_MILLIS = 467;
@IntDef({LARGE, SMALL}) @IntDef({LARGE, SMALL})
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@@ -90,7 +94,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
@VisibleForTesting AnimatorSet mClockInAnim = null; @VisibleForTesting AnimatorSet mClockInAnim = null;
@VisibleForTesting AnimatorSet mClockOutAnim = null; @VisibleForTesting AnimatorSet mClockOutAnim = null;
private ObjectAnimator mStatusAreaAnim = null; private AnimatorSet mStatusAreaAnim = null;
private int mClockSwitchYAmount; private int mClockSwitchYAmount;
@VisibleForTesting boolean mChildrenAreLaidOut = false; @VisibleForTesting boolean mChildrenAreLaidOut = false;
@@ -220,28 +224,34 @@ public class KeyguardClockSwitch extends RelativeLayout {
mStatusAreaAnim = null; mStatusAreaAnim = null;
View in, out; View in, out;
int direction = 1; float statusAreaYTranslation, clockInYTranslation, clockOutYTranslation;
float statusAreaYTranslation;
if (useLargeClock) { if (useLargeClock) {
out = mSmallClockFrame; out = mSmallClockFrame;
in = mLargeClockFrame; in = mLargeClockFrame;
if (indexOfChild(in) == -1) addView(in, 0); if (indexOfChild(in) == -1) addView(in, 0);
direction = -1;
statusAreaYTranslation = mSmallClockFrame.getTop() - mStatusArea.getTop() statusAreaYTranslation = mSmallClockFrame.getTop() - mStatusArea.getTop()
+ mSmartspaceTopOffset; + mSmartspaceTopOffset;
clockInYTranslation = 0;
clockOutYTranslation = 0; // Small clock translation is handled with statusArea
} else { } else {
in = mSmallClockFrame; in = mSmallClockFrame;
out = mLargeClockFrame; out = mLargeClockFrame;
statusAreaYTranslation = 0f; statusAreaYTranslation = 0f;
clockInYTranslation = 0f;
clockOutYTranslation = mClockSwitchYAmount * -1f;
// Must remove in order for notifications to appear in the proper place // Must remove in order for notifications to appear in the proper place, ideally this
// would happen after the out animation runs, but we can't guarantee that the
// nofications won't enter only after the out animation runs.
removeView(out); removeView(out);
} }
if (!animate) { if (!animate) {
out.setAlpha(0f); out.setAlpha(0f);
out.setTranslationY(clockOutYTranslation);
out.setVisibility(INVISIBLE); out.setVisibility(INVISIBLE);
in.setAlpha(1f); in.setAlpha(1f);
in.setTranslationY(clockInYTranslation);
in.setVisibility(VISIBLE); in.setVisibility(VISIBLE);
mStatusArea.setTranslationY(statusAreaYTranslation); mStatusArea.setTranslationY(statusAreaYTranslation);
return; return;
@@ -249,11 +259,10 @@ public class KeyguardClockSwitch extends RelativeLayout {
mClockOutAnim = new AnimatorSet(); mClockOutAnim = new AnimatorSet();
mClockOutAnim.setDuration(CLOCK_OUT_MILLIS); mClockOutAnim.setDuration(CLOCK_OUT_MILLIS);
mClockOutAnim.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN); mClockOutAnim.setInterpolator(Interpolators.LINEAR);
mClockOutAnim.playTogether( mClockOutAnim.playTogether(
ObjectAnimator.ofFloat(out, View.ALPHA, 0f), ObjectAnimator.ofFloat(out, ALPHA, 0f),
ObjectAnimator.ofFloat(out, View.TRANSLATION_Y, 0, ObjectAnimator.ofFloat(out, TRANSLATION_Y, clockOutYTranslation));
direction * -mClockSwitchYAmount));
mClockOutAnim.addListener(new AnimatorListenerAdapter() { mClockOutAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
if (mClockOutAnim == animation) { if (mClockOutAnim == animation) {
@@ -268,8 +277,9 @@ public class KeyguardClockSwitch extends RelativeLayout {
mClockInAnim = new AnimatorSet(); mClockInAnim = new AnimatorSet();
mClockInAnim.setDuration(CLOCK_IN_MILLIS); mClockInAnim.setDuration(CLOCK_IN_MILLIS);
mClockInAnim.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN); mClockInAnim.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
mClockInAnim.playTogether(ObjectAnimator.ofFloat(in, View.ALPHA, 1f), mClockInAnim.playTogether(
ObjectAnimator.ofFloat(in, View.TRANSLATION_Y, direction * mClockSwitchYAmount, 0)); ObjectAnimator.ofFloat(in, ALPHA, 1f),
ObjectAnimator.ofFloat(in, TRANSLATION_Y, clockInYTranslation));
mClockInAnim.setStartDelay(CLOCK_IN_START_DELAY_MILLIS); mClockInAnim.setStartDelay(CLOCK_IN_START_DELAY_MILLIS);
mClockInAnim.addListener(new AnimatorListenerAdapter() { mClockInAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
@@ -279,14 +289,14 @@ public class KeyguardClockSwitch extends RelativeLayout {
} }
}); });
mClockInAnim.start(); mStatusAreaAnim = new AnimatorSet();
mClockOutAnim.start(); mStatusAreaAnim.setStartDelay(STATUS_AREA_START_DELAY_MILLIS);
mStatusAreaAnim.setDuration(
mStatusAreaAnim = ObjectAnimator.ofFloat(mStatusArea, View.TRANSLATION_Y, useLargeClock ? STATUS_AREA_MOVE_UP_MILLIS : STATUS_AREA_MOVE_DOWN_MILLIS);
statusAreaYTranslation); mStatusAreaAnim.setInterpolator(Interpolators.EMPHASIZED);
mStatusAreaAnim.setStartDelay(useLargeClock ? STATUS_AREA_START_DELAY_MILLIS : 0L); mStatusAreaAnim.playTogether(
mStatusAreaAnim.setDuration(STATUS_AREA_MOVE_MILLIS); ObjectAnimator.ofFloat(mStatusArea, TRANSLATION_Y, statusAreaYTranslation),
mStatusAreaAnim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); ObjectAnimator.ofFloat(mSmallClockFrame, TRANSLATION_Y, statusAreaYTranslation));
mStatusAreaAnim.addListener(new AnimatorListenerAdapter() { mStatusAreaAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
if (mStatusAreaAnim == animation) { if (mStatusAreaAnim == animation) {
@@ -294,6 +304,9 @@ public class KeyguardClockSwitch extends RelativeLayout {
} }
} }
}); });
mClockInAnim.start();
mClockOutAnim.start();
mStatusAreaAnim.start(); mStatusAreaAnim.start();
} }

View File

@@ -19,6 +19,7 @@ package com.android.systemui.shared.clocks
import android.testing.AndroidTestingRunner import android.testing.AndroidTestingRunner
import android.view.LayoutInflater import android.view.LayoutInflater
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.app.animation.Interpolators
import com.android.systemui.R import com.android.systemui.R
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.TextAnimator import com.android.systemui.animation.TextAnimator
@@ -64,8 +65,8 @@ class AnimatableClockViewTest : SysuiTestCase() {
color = 200, color = 200,
strokeWidth = -1F, strokeWidth = -1F,
animate = false, animate = false,
duration = 350L, duration = 833L,
interpolator = null, interpolator = Interpolators.EMPHASIZED_DECELERATE,
delay = 0L, delay = 0L,
onAnimationEnd = null onAnimationEnd = null
) )
@@ -98,8 +99,8 @@ class AnimatableClockViewTest : SysuiTestCase() {
color = 200, color = 200,
strokeWidth = -1F, strokeWidth = -1F,
animate = true, animate = true,
duration = 350L, duration = 833L,
interpolator = null, interpolator = Interpolators.EMPHASIZED_DECELERATE,
delay = 0L, delay = 0L,
onAnimationEnd = null onAnimationEnd = null
) )