From f23e2d1e1634704f4d851985b05d38298b6e942f Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Fri, 17 Mar 2023 08:56:31 -0700 Subject: [PATCH] Keep foreground drawable centered during app open/close animation. For apps that use AdaptiveIcon, we used to animate the foreground drawable independently from the background. This is sometimes perceived as jank so we remove the animation since it is very subtle in the best case scenario. Bug: 268026344 Test: open/close apps/folders that use AdaptiveIcons Change-Id: I500bf56e04823757d511d909a93d3b30703249a1 --- .../launcher3/QuickstepTransitionManager.java | 8 +- .../quickstep/LauncherSwipeHandlerV2.java | 4 +- .../SwipeUpGestureTutorialController.java | 2 +- .../android/launcher3/views/ClipIconView.java | 100 +++--------------- .../launcher3/views/FloatingIconView.java | 9 +- 5 files changed, 24 insertions(+), 99 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index ea7eba3e8b..2bd439dba5 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -794,7 +794,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener if (initOnly) { // For the init pass, we want full alpha since the window is not yet ready. - floatingView.update(1f, 255, floatingIconBounds, percent, 0f, + floatingView.update(1f, floatingIconBounds, percent, 0f, mWindowRadius.value * scale, true /* isOpening */); return; } @@ -822,7 +822,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener matrix.postTranslate(windowTransX0, windowTransY0); } - floatingView.update(mIconAlpha.value, 255, floatingIconBounds, percent, 0f, + floatingView.update(mIconAlpha.value, floatingIconBounds, percent, 0f, mWindowRadius.value * scale, true /* isOpening */); builder.setMatrix(matrix) .setWindowCrop(crop) @@ -1381,8 +1381,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener windowTargetBounds, startWindowCornerRadius) { @Override public void onUpdate(RectF currentRectF, float progress) { - finalFloatingIconView.update(1f, 255 /* fgAlpha */, currentRectF, progress, - windowAlphaThreshold, getCornerRadius(progress), false); + finalFloatingIconView.update(1f, currentRectF, progress, windowAlphaThreshold, + getCornerRadius(progress), false); super.onUpdate(currentRectF, progress); } diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java index 315137441e..1dfad16d05 100644 --- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java +++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java @@ -139,8 +139,8 @@ public class LauncherSwipeHandlerV2 extends @Override public void update(RectF currentRect, float progress, float radius) { super.update(currentRect, progress, radius); - floatingIconView.update(1f /* alpha */, 255 /* fgAlpha */, currentRect, progress, - windowAlphaThreshold, radius, false); + floatingIconView.update(1f /* alpha */, currentRect, progress, windowAlphaThreshold, + radius, false); } }; } diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java index de9381833e..b3243ff31f 100644 --- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java @@ -354,7 +354,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController { mFakeIconView.setVisibility(View.VISIBLE); mFakeIconView.update(rect, progress, 1f - SHAPE_PROGRESS_DURATION /* shapeProgressStart */, - radius, 255, + radius, false, /* isOpening */ mFakeIconView, mDp); mFakeIconView.setAlpha(1); diff --git a/src/com/android/launcher3/views/ClipIconView.java b/src/com/android/launcher3/views/ClipIconView.java index d1f90e987f..694deadb63 100644 --- a/src/com/android/launcher3/views/ClipIconView.java +++ b/src/com/android/launcher3/views/ClipIconView.java @@ -43,9 +43,6 @@ import android.view.ViewGroup.MarginLayoutParams; import android.view.ViewOutlineProvider; import androidx.annotation.Nullable; -import androidx.dynamicanimation.animation.FloatPropertyCompat; -import androidx.dynamicanimation.animation.SpringAnimation; -import androidx.dynamicanimation.animation.SpringForce; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; @@ -63,39 +60,6 @@ public class ClipIconView extends View implements ClipPathView { private static final Rect sTmpRect = new Rect(); - // We spring the foreground drawable relative to the icon's movement in the DragLayer. - // We then use these two factor values to scale the movement of the fg within this view. - private static final int FG_TRANS_X_FACTOR = 60; - private static final int FG_TRANS_Y_FACTOR = 75; - - private static final FloatPropertyCompat mFgTransYProperty = - new FloatPropertyCompat("ClipIconViewFgTransY") { - @Override - public float getValue(ClipIconView view) { - return view.mFgTransY; - } - - @Override - public void setValue(ClipIconView view, float transY) { - view.mFgTransY = transY; - view.invalidate(); - } - }; - - private static final FloatPropertyCompat mFgTransXProperty = - new FloatPropertyCompat("ClipIconViewFgTransX") { - @Override - public float getValue(ClipIconView view) { - return view.mFgTransX; - } - - @Override - public void setValue(ClipIconView view, float transX) { - view.mFgTransX = transX; - view.invalidate(); - } - }; - private final int mBlurSizeOutline; private final boolean mIsRtl; @@ -114,11 +78,6 @@ public class ClipIconView extends View implements ClipPathView { private final Rect mOutline = new Rect(); private final Rect mFinalDrawableBounds = new Rect(); - private final SpringAnimation mFgSpringY; - private float mFgTransY; - private final SpringAnimation mFgSpringX; - private float mFgTransX; - public ClipIconView(Context context) { this(context, null); } @@ -132,22 +91,13 @@ public class ClipIconView extends View implements ClipPathView { mBlurSizeOutline = getResources().getDimensionPixelSize( R.dimen.blur_size_medium_outline); mIsRtl = Utilities.isRtl(getResources()); - - mFgSpringX = new SpringAnimation(this, mFgTransXProperty) - .setSpring(new SpringForce() - .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY) - .setStiffness(SpringForce.STIFFNESS_LOW)); - mFgSpringY = new SpringAnimation(this, mFgTransYProperty) - .setSpring(new SpringForce() - .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY) - .setStiffness(SpringForce.STIFFNESS_LOW)); } /** * Update the icon UI to match the provided parameters during an animation frame */ public void update(RectF rect, float progress, float shapeProgressStart, float cornerRadius, - int fgIconAlpha, boolean isOpening, View container, DeviceProfile dp) { + boolean isOpening, View container, DeviceProfile dp) { MarginLayoutParams lp = (MarginLayoutParams) container.getLayoutParams(); float dX = mIsRtl @@ -167,8 +117,7 @@ public class ClipIconView extends View implements ClipPathView { return; } - update(rect, progress, shapeProgressStart, cornerRadius, fgIconAlpha, isOpening, scale, - minSize, lp, dp); + update(rect, progress, shapeProgressStart, cornerRadius, isOpening, scale, minSize, dp); container.setPivotX(0); container.setPivotY(0); @@ -179,13 +128,7 @@ public class ClipIconView extends View implements ClipPathView { } private void update(RectF rect, float progress, float shapeProgressStart, float cornerRadius, - int fgIconAlpha, boolean isOpening, float scale, float minSize, - MarginLayoutParams parentLp, DeviceProfile dp) { - float dX = mIsRtl - ? rect.left - (dp.widthPx - parentLp.getMarginStart() - parentLp.width) - : rect.left - parentLp.getMarginStart(); - float dY = rect.top - parentLp.topMargin; - + boolean isOpening, float scale, float minSize, DeviceProfile dp) { // shapeRevealProgress = 1 when progress = shapeProgressStart + SHAPE_PROGRESS_DURATION float toMax = isOpening ? 1 / SHAPE_PROGRESS_DURATION : 1f; @@ -220,27 +163,17 @@ public class ClipIconView extends View implements ClipPathView { float drawableScale = (dp.isLandscape ? mOutline.width() : mOutline.height()) / minSize; setBackgroundDrawableBounds(drawableScale, dp.isLandscape); - if (isOpening) { - // Center align foreground - int height = mFinalDrawableBounds.height(); - int width = mFinalDrawableBounds.width(); - int diffY = dp.isLandscape ? 0 - : (int) (((height * drawableScale) - height) / 2); - int diffX = dp.isLandscape ? (int) (((width * drawableScale) - width) / 2) - : 0; - sTmpRect.set(mFinalDrawableBounds); - sTmpRect.offset(diffX, diffY); - mForeground.setBounds(sTmpRect); - } else { - mForeground.setAlpha(fgIconAlpha); - // Spring the foreground relative to the icon's movement within the DragLayer. - int diffX = (int) (dX / dp.availableWidthPx * FG_TRANS_X_FACTOR); - int diffY = (int) (dY / dp.availableHeightPx * FG_TRANS_Y_FACTOR); - - mFgSpringX.animateToFinalPosition(diffX); - mFgSpringY.animateToFinalPosition(diffY); - } + // Center align foreground + int height = mFinalDrawableBounds.height(); + int width = mFinalDrawableBounds.width(); + int diffY = dp.isLandscape ? 0 + : (int) (((height * drawableScale) - height) / 2); + int diffX = dp.isLandscape ? (int) (((width * drawableScale) - width) / 2) + : 0; + sTmpRect.set(mFinalDrawableBounds); + sTmpRect.offset(diffX, diffY); + mForeground.setBounds(sTmpRect); } invalidate(); invalidateOutline(); @@ -359,10 +292,7 @@ public class ClipIconView extends View implements ClipPathView { mBackground.draw(canvas); } if (mForeground != null) { - int count2 = canvas.save(); - canvas.translate(mFgTransX, mFgTransY); mForeground.draw(canvas); - canvas.restoreToCount(count2); } canvas.restoreToCount(count); } @@ -380,9 +310,5 @@ public class ClipIconView extends View implements ClipPathView { mRevealAnimator = null; mTaskCornerRadius = 0; mOutline.setEmpty(); - mFgTransY = 0; - mFgSpringX.cancel(); - mFgTransX = 0; - mFgSpringY.cancel(); } } diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index e233e4643a..172b40517a 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -146,17 +146,16 @@ public class FloatingIconView extends FrameLayout implements /** * Positions this view to match the size and location of {@param rect}. * @param alpha The alpha[0, 1] of the entire floating view. - * @param fgIconAlpha The alpha[0-255] of the foreground layer of the icon (if applicable). * @param progress A value from [0, 1] that represents the animation progress. * @param shapeProgressStart The progress value at which to start the shape reveal. * @param cornerRadius The corner radius of {@param rect}. * @param isOpening True if view is used for app open animation, false for app close animation. */ - public void update(float alpha, int fgIconAlpha, RectF rect, float progress, - float shapeProgressStart, float cornerRadius, boolean isOpening) { + public void update(float alpha, RectF rect, float progress, float shapeProgressStart, + float cornerRadius, boolean isOpening) { setAlpha(alpha); - mClipIconView.update(rect, progress, shapeProgressStart, cornerRadius, fgIconAlpha, - isOpening, this, mLauncher.getDeviceProfile()); + mClipIconView.update(rect, progress, shapeProgressStart, cornerRadius, isOpening, this, + mLauncher.getDeviceProfile()); } @Override