Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f23e2d1e authored by Jon Miranda's avatar Jon Miranda
Browse files

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
parent 713931ec
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -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);
                }
+2 −2
Original line number Diff line number Diff line
@@ -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);
            }
        };
    }
+1 −1
Original line number Diff line number Diff line
@@ -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);
+13 −87
Original line number Diff line number Diff line
@@ -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<ClipIconView> mFgTransYProperty =
            new FloatPropertyCompat<ClipIconView>("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<ClipIconView> mFgTransXProperty =
            new FloatPropertyCompat<ClipIconView>("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,7 +163,7 @@ 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();
@@ -231,16 +174,6 @@ public class ClipIconView extends View implements ClipPathView {
            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);
            }
        }
        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();
    }
}
+4 −5
Original line number Diff line number Diff line
@@ -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