From 2da1da30760c7abb576a5fbefc6ec4d12040a2b2 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Fri, 10 May 2019 08:50:49 -0700 Subject: [PATCH] Initial app open/close polish using tuned values. * Rect and radius now match the app window size. Bug: 124510042 Bug: 122843905 Change-Id: Ibc85bfe1d75d01cefe00b6bf32557e04a0ee4716 --- .../WindowTransformSwipeHandler.java | 9 +-- .../quickstep/util/RectFSpringAnim.java | 5 +- .../QuickstepAppTransitionManagerImpl.java | 23 ++++--- .../launcher3/anim/FlingSpringAnim.java | 4 +- .../launcher3/views/FloatingIconView.java | 68 +++++++++---------- 5 files changed, 58 insertions(+), 51 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index 49c95f12c9..d927d83068 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -1095,14 +1095,15 @@ public class WindowTransformSwipeHandler homeAnim.setPlayFraction(progress); - float iconAlpha = Utilities.mapToRange(interpolatedProgress, 0, - windowAlphaThreshold, 0f, 1f, Interpolators.LINEAR); - mTransformParams.setCurrentRectAndTargetAlpha(currentRect, 1f - iconAlpha); + float windowAlpha = Utilities.mapToRange(interpolatedProgress, 0, + windowAlphaThreshold, 1f, 0f, Interpolators.LINEAR); + mTransformParams.setProgress(progress) + .setCurrentRectAndTargetAlpha(currentRect, windowAlpha); mClipAnimationHelper.applyTransform(targetSet, mTransformParams, false /* launcherOnTop */); if (isFloatingIconView) { - ((FloatingIconView) floatingView).update(currentRect, iconAlpha, progress, + ((FloatingIconView) floatingView).update(currentRect, 1f, progress, windowAlphaThreshold, mClipAnimationHelper.getCurrentCornerRadius(), false); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java index 40b9c4dcec..09db6952f7 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RectFSpringAnim.java @@ -33,6 +33,8 @@ import com.android.launcher3.anim.FlingSpringAnim; import java.util.ArrayList; import java.util.List; +import static com.android.launcher3.anim.Interpolators.DEACCEL; + /** * Applies spring forces to animate from a starting rect to a target rect, * while providing update callbacks to the caller. @@ -45,7 +47,7 @@ public class RectFSpringAnim { * can be done in parallel at a fixed duration. Update callbacks are sent based on the progress * of this animation, while the end callback is sent after all animations finish. */ - private static final long RECT_SCALE_DURATION = 180; + private static final long RECT_SCALE_DURATION = 250; private static final FloatPropertyCompat RECT_CENTER_X = new FloatPropertyCompat("rectCenterXSpring") { @@ -148,6 +150,7 @@ public class RectFSpringAnim { mRectScaleAnim = ObjectAnimator.ofPropertyValuesHolder(this, PropertyValuesHolder.ofFloat(RECT_SCALE_PROGRESS, 1)) .setDuration(RECT_SCALE_DURATION); + mRectScaleAnim.setInterpolator(DEACCEL); mRectScaleAnim.addListener(new AnimationSuccessListener() { @Override public void onAnimationSuccess(Animator animator) { diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java index 3b75304b7c..7dd4df7d69 100644 --- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java +++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java @@ -104,16 +104,18 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION = "android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS"; - private static final long APP_LAUNCH_DURATION = 500; + private static final long APP_LAUNCH_DURATION = 450; // Use a shorter duration for x or y translation to create a curve effect - private static final long APP_LAUNCH_CURVED_DURATION = APP_LAUNCH_DURATION / 2; + private static final long APP_LAUNCH_CURVED_DURATION = 250; private static final long APP_LAUNCH_ALPHA_DURATION = 50; + private static final long APP_LAUNCH_ALPHA_START_DELAY = 50; // We scale the durations for the downward app launch animations (minus the scale animation). private static final float APP_LAUNCH_DOWN_DUR_SCALE_FACTOR = 0.8f; private static final long APP_LAUNCH_DOWN_DURATION = (long) (APP_LAUNCH_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR); - private static final long APP_LAUNCH_DOWN_CURVED_DURATION = APP_LAUNCH_DOWN_DURATION / 2; + private static final long APP_LAUNCH_DOWN_CURVED_DURATION = + (long) (APP_LAUNCH_CURVED_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR); private static final long APP_LAUNCH_ALPHA_DOWN_DURATION = (long) (APP_LAUNCH_ALPHA_DURATION * APP_LAUNCH_DOWN_DUR_SCALE_FACTOR); @@ -475,17 +477,18 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans float shapeRevealDuration = APP_LAUNCH_DURATION * SHAPE_PROGRESS_DURATION; final float windowRadius = mDeviceProfile.isMultiWindowMode - ? 0 : getWindowCornerRadius(mLauncher.getResources()); - + ? 0 : getWindowCornerRadius(mLauncher.getResources()); appAnimator.addUpdateListener(new MultiValueUpdateListener() { FloatProp mDx = new FloatProp(0, dX, 0, xDuration, AGGRESSIVE_EASE); FloatProp mDy = new FloatProp(0, dY, 0, yDuration, AGGRESSIVE_EASE); FloatProp mIconScale = new FloatProp(initialStartScale, scale, 0, APP_LAUNCH_DURATION, EXAGGERATED_EASE); - FloatProp mIconAlpha = new FloatProp(1f, 0f, shapeRevealDuration, alphaDuration, - LINEAR); + FloatProp mIconAlpha = new FloatProp(1f, 0f, APP_LAUNCH_ALPHA_START_DELAY, + alphaDuration, LINEAR); FloatProp mCropHeight = new FloatProp(windowTargetBounds.width(), - windowTargetBounds.height(), 0, shapeRevealDuration, AGGRESSIVE_EASE); + windowTargetBounds.height(), 0, APP_LAUNCH_DURATION, EXAGGERATED_EASE); + FloatProp mWindowRadius = new FloatProp(windowTargetBounds.width() / 2f, + windowRadius, 0, APP_LAUNCH_DURATION, EXAGGERATED_EASE); @Override public void onUpdate(float percent) { @@ -518,6 +521,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans float transX0 = temp.left - offsetX; float transY0 = temp.top - offsetY; + float croppedHeight = (windowTargetBounds.height() - crop.height()) * scale; SurfaceParams[] params = new SurfaceParams[targets.length]; for (int i = targets.length - 1; i >= 0; i--) { RemoteAnimationTargetCompat target = targets[i]; @@ -529,8 +533,9 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans matrix.postTranslate(transX0, transY0); targetCrop = crop; alpha = 1f - mIconAlpha.value; - cornerRadius = windowRadius; + cornerRadius = mWindowRadius.value; matrix.mapRect(currentBounds, targetBounds); + currentBounds.bottom -= croppedHeight; mFloatingView.update(currentBounds, mIconAlpha.value, percent, 0f, cornerRadius * scale, true /* isOpening */); } else { diff --git a/src/com/android/launcher3/anim/FlingSpringAnim.java b/src/com/android/launcher3/anim/FlingSpringAnim.java index bb0f855d8c..3d981c136c 100644 --- a/src/com/android/launcher3/anim/FlingSpringAnim.java +++ b/src/com/android/launcher3/anim/FlingSpringAnim.java @@ -30,8 +30,8 @@ public class FlingSpringAnim { private static final float FLING_FRICTION = 1.5f; // Have the spring pull towards the target if we've slowed down too much before reaching it. private static final float FLING_END_THRESHOLD_PX = 50f; - private static final float SPRING_STIFFNESS = 350f; - private static final float SPRING_DAMPING = SpringForce.DAMPING_RATIO_LOW_BOUNCY; + private static final float SPRING_STIFFNESS = 200; + private static final float SPRING_DAMPING = 0.85f; private final FlingAnimation mFlingAnim; private SpringAnimation mSpringAnim; diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index 787c93ce97..73f11b22d4 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -98,10 +98,9 @@ public class FloatingIconView extends View implements private RectF mPositionOut; private Runnable mOnTargetChangeRunnable; + private final Rect mOutline = new Rect(); private final Rect mFinalDrawableBounds = new Rect(); private final Rect mBgDrawableBounds = new Rect(); - private float mBgDrawableStartScale = 1f; - private float mBgDrawableEndScale = 1f; private AnimatorSet mFadeAnimatorSet; private ListenerView mListenerView; @@ -143,11 +142,10 @@ public class FloatingIconView extends View implements setTranslationX(dX); setTranslationY(dY); - float scaleX = rect.width() / (float) lp.width; - float scaleY = rect.height() / (float) lp.height; - float scale = mIsAdaptiveIcon && !isOpening ? Math.max(scaleX, scaleY) - : Math.min(scaleX, scaleY); - scale = Math.max(1f, scale); + float minSize = Math.min(lp.width, lp.height); + float scaleX = rect.width() / minSize; + float scaleY = rect.height() / minSize; + float scale = Math.max(1f, Math.min(scaleX, scaleY)); setPivotX(0); setPivotY(0); @@ -160,27 +158,27 @@ public class FloatingIconView extends View implements Math.max(shapeProgressStart, progress), shapeProgressStart, 1f, 0, toMax, LINEAR), 0, 1); - mTaskCornerRadius = cornerRadius; - if (mIsAdaptiveIcon && shapeRevealProgress >= 0) { - if (mRevealAnimator == null) { - mRevealAnimator = (ValueAnimator) IconShape.getShape().createRevealAnimator(this, - mStartRevealRect, mEndRevealRect, mTaskCornerRadius / scale, !isOpening); - mRevealAnimator.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mRevealAnimator = null; - } - }); - mRevealAnimator.start(); - // We pause here so we can set the current fraction ourselves. - mRevealAnimator.pause(); + mOutline.bottom = (int) (rect.height() / scale); + mTaskCornerRadius = cornerRadius / scale; + if (mIsAdaptiveIcon) { + if (!isOpening && shapeRevealProgress >= 0) { + if (mRevealAnimator == null) { + mRevealAnimator = (ValueAnimator) IconShape.getShape().createRevealAnimator( + this, mStartRevealRect, mOutline, mTaskCornerRadius, !isOpening); + mRevealAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mRevealAnimator = null; + } + }); + mRevealAnimator.start(); + // We pause here so we can set the current fraction ourselves. + mRevealAnimator.pause(); + } + mRevealAnimator.setCurrentFraction(shapeRevealProgress); } - mRevealAnimator.setCurrentFraction(shapeRevealProgress); - - float bgScale = (mBgDrawableEndScale * shapeRevealProgress) + mBgDrawableStartScale - * (1 - shapeRevealProgress); - setBackgroundDrawableBounds(bgScale); + setBackgroundDrawableBounds(mOutline.height() / minSize); } invalidate(); invalidateOutline(); @@ -363,24 +361,22 @@ public class FloatingIconView extends View implements layout(lp.leftMargin, lp.topMargin, lp.leftMargin + lp.width, lp.topMargin + lp.height); - Rect rectOutline = new Rect(); float scale = Math.max((float) lp.height / originalHeight, (float) lp.width / originalWidth); + float bgDrawableStartScale; if (isOpening) { - mBgDrawableStartScale = 1f; - mBgDrawableEndScale = scale; - rectOutline.set(0, 0, originalWidth, originalHeight); + bgDrawableStartScale = 1f; + mOutline.set(0, 0, originalWidth, originalHeight); } else { - mBgDrawableStartScale = scale; - mBgDrawableEndScale = 1f; - rectOutline.set(0, 0, lp.width, lp.height); + bgDrawableStartScale = scale; + mOutline.set(0, 0, lp.width, lp.height); } + setBackgroundDrawableBounds(bgDrawableStartScale); mEndRevealRect.set(0, 0, lp.width, lp.height); - setBackgroundDrawableBounds(mBgDrawableStartScale); setOutlineProvider(new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { - outline.setRoundRect(rectOutline, mTaskCornerRadius); + outline.setRoundRect(mOutline, mTaskCornerRadius); } }); setClipToOutline(true); @@ -630,5 +626,7 @@ public class FloatingIconView extends View implements mListenerView.setListener(null); mOriginalIcon = null; mOnTargetChangeRunnable = null; + mTaskCornerRadius = 0; + mOutline.setEmpty(); } }