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

Commit 62590844 authored by Charlie Anderson's avatar Charlie Anderson
Browse files

Adds new motion animation for U popups

Bug: b/247880037
Test: manually on tablet
Change-Id: I8677cef39a5dc4094cad38f42b9314ac37b95fc2
parent 01c1dff4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
        clipToOutline = true

        shouldScaleArrow = true
        mIsArrowRotated = true
        // This synchronizes the arrow and menu to open at the same time
        OPEN_CHILD_FADE_START_DELAY = OPEN_FADE_START_DELAY
        OPEN_CHILD_FADE_DURATION = OPEN_FADE_DURATION
+106 −3
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import static androidx.core.content.ContextCompat.getColorStateList;

import static com.android.launcher3.anim.Interpolators.ACCELERATED_EASE;
import static com.android.launcher3.anim.Interpolators.DECELERATED_EASE;
import static com.android.launcher3.anim.Interpolators.EMPHASIZED_ACCELERATE;
import static com.android.launcher3.anim.Interpolators.EMPHASIZED_DECELERATE;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_MATERIAL_U_POPUP;

@@ -37,11 +39,13 @@ import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.util.AttributeSet;
import android.util.Pair;
import android.util.Property;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
import android.widget.FrameLayout;

import androidx.annotation.Nullable;
@@ -81,6 +85,19 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
    protected int CLOSE_CHILD_FADE_START_DELAY = 0;
    protected int CLOSE_CHILD_FADE_DURATION = 140;

    private static final int OPEN_DURATION_U = 200;
    private static final int OPEN_FADE_START_DELAY_U = 0;
    private static final int OPEN_FADE_DURATION_U = 83;
    private static final int OPEN_CHILD_FADE_START_DELAY_U = 0;
    private static final int OPEN_CHILD_FADE_DURATION_U = 83;
    private static final int OPEN_OVERSHOOT_DURATION_U = 200;

    private static final int CLOSE_DURATION_U  = 233;
    private static final int CLOSE_FADE_START_DELAY_U = 150;
    private static final int CLOSE_FADE_DURATION_U = 83;
    private static final int CLOSE_CHILD_FADE_START_DELAY_U = 150;
    private static final int CLOSE_CHILD_FADE_DURATION_U = 83;

    protected final Rect mTempRect = new Rect();

    protected final LayoutInflater mInflater;
@@ -104,6 +121,7 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
    protected AnimatorSet mOpenCloseAnimator;
    protected boolean mDeferContainerRemoval;
    protected boolean shouldScaleArrow = false;
    protected boolean mIsArrowRotated = false;

    private final GradientDrawable mRoundedTop;
    private final GradientDrawable mRoundedBottom;
@@ -591,10 +609,24 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>

    protected void animateOpen() {
        setVisibility(View.VISIBLE);

        mOpenCloseAnimator = getOpenCloseAnimator(true, OPEN_DURATION, OPEN_FADE_START_DELAY,
                OPEN_FADE_DURATION, OPEN_CHILD_FADE_START_DELAY, OPEN_CHILD_FADE_DURATION,
        mOpenCloseAnimator = ENABLE_MATERIAL_U_POPUP.get()
                ? getMaterialUOpenCloseAnimator(
                        true,
                        OPEN_DURATION_U,
                        OPEN_FADE_START_DELAY_U,
                        OPEN_FADE_DURATION_U,
                        OPEN_CHILD_FADE_START_DELAY_U,
                        OPEN_CHILD_FADE_DURATION_U,
                        EMPHASIZED_DECELERATE)
                : getOpenCloseAnimator(
                        true,
                        OPEN_DURATION,
                        OPEN_FADE_START_DELAY,
                        OPEN_FADE_DURATION,
                        OPEN_CHILD_FADE_START_DELAY,
                        OPEN_CHILD_FADE_DURATION,
                        DECELERATED_EASE);

        onCreateOpenAnimation(mOpenCloseAnimator);
        mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
@@ -680,6 +712,24 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
        mOpenCloseAnimator = getOpenCloseAnimator(false, CLOSE_DURATION, CLOSE_FADE_START_DELAY,
                CLOSE_FADE_DURATION, CLOSE_CHILD_FADE_START_DELAY, CLOSE_CHILD_FADE_DURATION,
                ACCELERATED_EASE);

        mOpenCloseAnimator = ENABLE_MATERIAL_U_POPUP.get()
                ? getMaterialUOpenCloseAnimator(
                        false,
                        CLOSE_DURATION_U,
                        CLOSE_FADE_START_DELAY_U,
                        CLOSE_FADE_DURATION_U,
                        CLOSE_CHILD_FADE_START_DELAY_U,
                        CLOSE_CHILD_FADE_DURATION_U,
                        EMPHASIZED_ACCELERATE)
                : getOpenCloseAnimator(false,
                        CLOSE_DURATION,
                        CLOSE_FADE_START_DELAY,
                        CLOSE_FADE_DURATION,
                        CLOSE_CHILD_FADE_START_DELAY,
                        CLOSE_CHILD_FADE_DURATION,
                        ACCELERATED_EASE);

        onCreateCloseAnimation(mOpenCloseAnimator);
        mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
@@ -695,6 +745,59 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
        mOpenCloseAnimator.start();
    }

    protected AnimatorSet getMaterialUOpenCloseAnimator(boolean isOpening, int scaleDuration,
            int fadeStartDelay, int fadeDuration, int childFadeStartDelay, int childFadeDuration,
            Interpolator interpolator) {

        int arrowCenter = mArrowOffsetHorizontal + mArrowWidth / 2;
        if (mIsArrowRotated) {
            setPivotX(mIsLeftAligned ? 0f : getMeasuredWidth());
            setPivotY(arrowCenter);
        } else {
            setPivotX(mIsLeftAligned ? arrowCenter : getMeasuredWidth() - arrowCenter);
            setPivotY(mIsAboveIcon ? getMeasuredHeight() : 0f);
        }

        float[] alphaValues = isOpening ? new float[] {0, 1} : new float[] {1, 0};
        float[] scaleValues = isOpening ? new float[] {0.5f, 1.02f} : new float[] {1f, 0.5f};
        Animator alpha = getAnimatorOfFloat(this, View.ALPHA, fadeDuration, fadeStartDelay,
                LINEAR, alphaValues);
        Animator arrowAlpha = getAnimatorOfFloat(mArrow, View.ALPHA, fadeDuration, fadeStartDelay,
                LINEAR, alphaValues);
        Animator scaleY = getAnimatorOfFloat(this, View.SCALE_Y, scaleDuration, 0, interpolator,
                scaleValues);
        Animator scaleX = getAnimatorOfFloat(this, View.SCALE_X, scaleDuration, 0, interpolator,
                scaleValues);

        final AnimatorSet animatorSet = new AnimatorSet();
        if (isOpening) {
            float[] scaleValuesOvershoot = new float[] {1.02f, 1f};
            PathInterpolator overshootInterpolator = new PathInterpolator(0.3f, 0, 0.33f, 1f);
            Animator overshootY = getAnimatorOfFloat(this, View.SCALE_Y,
                    OPEN_OVERSHOOT_DURATION_U, scaleDuration, overshootInterpolator,
                    scaleValuesOvershoot);
            Animator overshootX = getAnimatorOfFloat(this, View.SCALE_X,
                    OPEN_OVERSHOOT_DURATION_U, scaleDuration, overshootInterpolator,
                    scaleValuesOvershoot);

            animatorSet.playTogether(alpha, arrowAlpha, scaleY, scaleX, overshootX, overshootY);
        } else {
            animatorSet.playTogether(alpha, arrowAlpha, scaleY, scaleX);
        }

        fadeInChildViews(this, alphaValues, childFadeStartDelay, childFadeDuration, animatorSet);
        return animatorSet;
    }

    private Animator getAnimatorOfFloat(View view, Property<View, Float> property,
            int duration, int startDelay, Interpolator interpolator,  float... values) {
        Animator animator = ObjectAnimator.ofFloat(view, property, values);
        animator.setDuration(duration);
        animator.setInterpolator(interpolator);
        animator.setStartDelay(startDelay);
        return animator;
    }

    /**
     * Called when creating the open transition allowing subclass can add additional animations.
     */