From 271638574f38743ca27931591fd36d7859b780e5 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Thu, 18 Jun 2020 13:03:01 -0700 Subject: [PATCH] Add spring to workspace scale when going from Hint state to Normal state. Bug: 151768994 Change-Id: If03d39e5ef6319355a7691d60fc0152de2fc3cec --- .../QuickstepAtomicAnimationFactory.java | 13 ++++ ...ButtonNavbarToOverviewTouchController.java | 28 ++++++++- res/values/config.xml | 8 +++ .../WorkspaceStateTransitionAnimation.java | 59 ++++++++++++++++--- .../android/launcher3/states/HintState.java | 12 +++- 5 files changed, 110 insertions(+), 10 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java index ba8656db76..a0af79743b 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java @@ -24,6 +24,7 @@ import static com.android.launcher3.LauncherState.HOTSEAT_ICONS; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; import static com.android.launcher3.LauncherState.OVERVIEW_PEEK; +import static com.android.launcher3.WorkspaceStateTransitionAnimation.getSpringScaleAnimator; import static com.android.launcher3.anim.Interpolators.ACCEL; import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7; @@ -90,6 +91,10 @@ public class QuickstepAtomicAnimationFactory extends protected static final int NEXT_INDEX = RecentsAtomicAnimationFactory.NEXT_INDEX + MY_ANIM_COUNT; + // Due to use of physics, duration may differ between devices so we need to calculate and + // cache the value. + private int mHintToNormalDuration = -1; + public static final long ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW = 300; public QuickstepAtomicAnimationFactory(QuickstepLauncher activity) { @@ -221,6 +226,14 @@ public class QuickstepAtomicAnimationFactory extends config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, translationInterpolator); config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, translationInterpolator); config.setInterpolator(ANIM_OVERVIEW_FADE, OVERSHOOT_1_2); + } else if (fromState == HINT_STATE && toState == NORMAL) { + config.setInterpolator(ANIM_DEPTH, DEACCEL_3); + if (mHintToNormalDuration == -1) { + ValueAnimator va = getSpringScaleAnimator(mActivity, mActivity.getWorkspace(), + toState.getWorkspaceScaleAndTranslation(mActivity).scale); + mHintToNormalDuration = (int) va.getDuration(); + } + config.duration = Math.max(config.duration, mHintToNormalDuration); } } } diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java index 4cc8256360..9316938c45 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java @@ -26,6 +26,7 @@ import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC; import android.animation.Animator; import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.graphics.PointF; import android.util.Log; @@ -35,6 +36,7 @@ import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; +import com.android.launcher3.graphics.OverviewScrim; import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.testing.TestProtocol; @@ -65,6 +67,9 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo // The last recorded displacement before we reached overview. private PointF mStartDisplacement = new PointF(); + // Normal to Hint animation has flag SKIP_OVERVIEW, so we update this scrim with this animator. + private ObjectAnimator mNormalToHintOverviewScrimAnimator; + public NoButtonNavbarToOverviewTouchController(Launcher l) { super(l); mRecentsView = l.getOverviewPanel(); @@ -110,10 +115,30 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo @Override public void onDragStart(boolean start, float startDisplacement) { super.onDragStart(start, startDisplacement); - + if (mFromState == NORMAL && mToState == HINT_STATE) { + mNormalToHintOverviewScrimAnimator = ObjectAnimator.ofFloat( + mLauncher.getDragLayer().getOverviewScrim(), + OverviewScrim.SCRIM_PROGRESS, + mFromState.getOverviewScrimAlpha(mLauncher), + mToState.getOverviewScrimAlpha(mLauncher)); + } mReachedOverview = false; } + @Override + protected void updateProgress(float fraction) { + super.updateProgress(fraction); + if (mNormalToHintOverviewScrimAnimator != null) { + mNormalToHintOverviewScrimAnimator.setCurrentFraction(fraction); + } + } + + @Override + public void onDragEnd(float velocity) { + super.onDragEnd(velocity); + mNormalToHintOverviewScrimAnimator = null; + } + @Override protected void updateSwipeCompleteAnimation(ValueAnimator animator, long expectedDuration, LauncherState targetState, float velocity, boolean isFling) { @@ -132,6 +157,7 @@ public class NoButtonNavbarToOverviewTouchController extends FlingAndHoldTouchCo if (mCurrentAnimation == null) { return; } + mNormalToHintOverviewScrimAnimator = null; mCurrentAnimation.dispatchOnCancelWithoutCancelRunnable(() -> { mLauncher.getStateManager().goToState(OVERVIEW, true, () -> { mReachedOverview = true; diff --git a/res/values/config.xml b/res/values/config.xml index 4cbc597f6f..ca253259e4 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -144,6 +144,10 @@ 150 3dp + 0.7 + 200 + 0.3dp + 18dp 10dp @@ -175,6 +179,10 @@ @dimen/swipe_up_fling_min_visible_change @dimen/swipe_up_y_overshoot + + @dimen/hint_scale_damping_ratio + @dimen/hint_scale_stiffness + @dimen/hint_scale_velocity_dp_per_s diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index 06a73dbc28..cd938e1201 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -16,6 +16,8 @@ package com.android.launcher3; +import static androidx.dynamicanimation.animation.DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE; + import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA; @@ -23,11 +25,13 @@ import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X; import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y; import static com.android.launcher3.LauncherState.FLAG_HAS_SYS_UI_SCRIM; import static com.android.launcher3.LauncherState.FLAG_WORKSPACE_HAS_BACKGROUNDS; +import static com.android.launcher3.LauncherState.HINT_STATE; import static com.android.launcher3.LauncherState.HOTSEAT_ICONS; +import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.ZOOM_OUT; import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER; -import static com.android.launcher3.graphics.WorkspaceAndHotseatScrim.SCRIM_PROGRESS; +import static com.android.launcher3.graphics.Scrim.SCRIM_PROGRESS; import static com.android.launcher3.graphics.WorkspaceAndHotseatScrim.SYSUI_PROGRESS; import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_SCALE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_TRANSLATE; @@ -35,6 +39,7 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_F import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE; +import android.animation.ValueAnimator; import android.view.View; import android.view.animation.Interpolator; @@ -43,8 +48,11 @@ import com.android.launcher3.LauncherState.ScaleAndTranslation; import com.android.launcher3.allapps.AllAppsContainerView; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PropertySetter; +import com.android.launcher3.anim.SpringAnimationBuilder; import com.android.launcher3.graphics.WorkspaceAndHotseatScrim; import com.android.launcher3.states.StateAnimationConfig; +import com.android.launcher3.util.DynamicResource; +import com.android.systemui.plugins.ResourceProvider; /** * Manages the animations between each of the workspace states. @@ -104,17 +112,32 @@ public class WorkspaceStateTransitionAnimation { View qsbView = qsbScaleView.getSearchView(); if (playAtomicComponent) { Interpolator scaleInterpolator = config.getInterpolator(ANIM_WORKSPACE_SCALE, ZOOM_OUT); - propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator); + LauncherState fromState = mLauncher.getStateManager().getState(); + boolean shouldSpring = propertySetter instanceof PendingAnimation + && fromState == HINT_STATE && state == NORMAL; + if (shouldSpring) { + ((PendingAnimation) propertySetter).add(getSpringScaleAnimator(mLauncher, + mWorkspace, mNewScale)); + } else { + propertySetter.setFloat(mWorkspace, SCALE_PROPERTY, mNewScale, scaleInterpolator); + } setPivotToScaleWithWorkspace(hotseat); setPivotToScaleWithWorkspace(qsbScaleView); float hotseatScale = hotseatScaleAndTranslation.scale; - Interpolator hotseatScaleInterpolator = config.getInterpolator(ANIM_HOTSEAT_SCALE, - scaleInterpolator); - propertySetter.setFloat(hotseat, SCALE_PROPERTY, hotseatScale, - hotseatScaleInterpolator); - propertySetter.setFloat(qsbScaleView, SCALE_PROPERTY, qsbScaleAndTranslation.scale, - hotseatScaleInterpolator); + if (shouldSpring) { + PendingAnimation pa = (PendingAnimation) propertySetter; + pa.add(getSpringScaleAnimator(mLauncher, hotseat, hotseatScale)); + pa.add(getSpringScaleAnimator(mLauncher, qsbScaleView, + qsbScaleAndTranslation.scale)); + } else { + Interpolator hotseatScaleInterpolator = config.getInterpolator(ANIM_HOTSEAT_SCALE, + scaleInterpolator); + propertySetter.setFloat(hotseat, SCALE_PROPERTY, hotseatScale, + hotseatScaleInterpolator); + propertySetter.setFloat(qsbScaleView, SCALE_PROPERTY, qsbScaleAndTranslation.scale, + hotseatScaleInterpolator); + } float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0; propertySetter.setViewAlpha(hotseat, hotseatIconsAlpha, fadeInterpolator); @@ -191,4 +214,24 @@ public class WorkspaceStateTransitionAnimation { pageAlpha, fadeInterpolator); } } + + /** + * Returns a spring based animator for the scale property of {@param v}. + */ + public static ValueAnimator getSpringScaleAnimator(Launcher launcher, View v, float scale) { + ResourceProvider rp = DynamicResource.provider(launcher); + float damping = rp.getFloat(R.dimen.hint_scale_damping_ratio); + float stiffness = rp.getFloat(R.dimen.hint_scale_stiffness); + float velocityPxPerS = rp.getDimension(R.dimen.hint_scale_velocity_dp_per_s); + + return new SpringAnimationBuilder(v.getContext()) + .setStiffness(stiffness) + .setDampingRatio(damping) + .setMinimumVisibleChange(MIN_VISIBLE_CHANGE_SCALE) + .setEndValue(scale) + .setStartValue(SCALE_PROPERTY.get(v)) + .setStartVelocity(velocityPxPerS) + .build(v, SCALE_PROPERTY); + + } } \ No newline at end of file diff --git a/src/com/android/launcher3/states/HintState.java b/src/com/android/launcher3/states/HintState.java index 9ea8436da5..b8a184fcfc 100644 --- a/src/com/android/launcher3/states/HintState.java +++ b/src/com/android/launcher3/states/HintState.java @@ -38,9 +38,19 @@ public class HintState extends LauncherState { return 80; } + @Override + protected float getDepthUnchecked(Context context) { + return 0.15f; + } + + @Override + public float getOverviewScrimAlpha(Launcher launcher) { + return 0.4f; + } + @Override public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) { - return new ScaleAndTranslation(0.9f, 0, 0); + return new ScaleAndTranslation(0.92f, 0, 0); } @Override