Add spring to workspace scale when going from Hint state to Normal state.
Bug: 151768994
Change-Id: If03d39e5ef6319355a7691d60fc0152de2fc3cec
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 ba8656d..a0af797 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.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 @@
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 @@
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 4cc8256..9316938 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 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.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 @@
// 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,11 +115,31 @@
@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) {
super.updateSwipeCompleteAnimation(animator, expectedDuration, targetState, velocity,
@@ -132,6 +157,7 @@
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 4cbc597..ca25325 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -144,6 +144,10 @@
<item name="staggered_stiffness" type="dimen" format="float">150</item>
<dimen name="unlock_staggered_velocity_dp_per_s">3dp</dimen>
+ <item name="hint_scale_damping_ratio" type="dimen" format="float">0.7</item>
+ <item name="hint_scale_stiffness" type="dimen" format="float">200</item>
+ <dimen name="hint_scale_velocity_dp_per_s">0.3dp</dimen>
+
<!-- Swipe up to home related -->
<dimen name="swipe_up_fling_min_visible_change">18dp</dimen>
<dimen name="swipe_up_y_overshoot">10dp</dimen>
@@ -175,6 +179,10 @@
<item>@dimen/swipe_up_fling_min_visible_change</item>
<item>@dimen/swipe_up_y_overshoot</item>
+
+ <item>@dimen/hint_scale_damping_ratio</item>
+ <item>@dimen/hint_scale_stiffness</item>
+ <item>@dimen/hint_scale_velocity_dp_per_s</item>
</array>
<string-array name="live_wallpapers_remove_sysui_scrims">
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 06a73db..cd938e1 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_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_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.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 @@
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 @@
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 9ea8436..b8a184f 100644
--- a/src/com/android/launcher3/states/HintState.java
+++ b/src/com/android/launcher3/states/HintState.java
@@ -39,8 +39,18 @@
}
@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