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

Commit a37f3f2c authored by Ats Jenk's avatar Ats Jenk
Browse files

Animate in desktop app select toast

Add an animation for the desktop app select toast.
Played when the toast is added to the screen.

Bug: 261234402
Test: have an app on desktop, swipe up to home, verify that the toast
  has an appear animation, per the spec
Test: when toast is visible, tap on cancel button, observe toast fades
  out
Test: when toast is visible, launch an app, verify toast fades out
Change-Id: I593d6c326d6d638f1bc06e8c6add31b0244e4cb5
parent 8fe538b1
Loading
Loading
Loading
Loading
+83 −12
Original line number Diff line number Diff line
@@ -15,16 +15,24 @@
 */
package com.android.quickstep.views;

import static com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE;
import static com.android.app.animation.Interpolators.LINEAR;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;

import androidx.annotation.Nullable;

import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;

/**
 * Floating view show on launcher home screen that notifies the user that an app will be launched to
@@ -32,13 +40,21 @@ import com.android.launcher3.R;
 */
public class DesktopAppSelectView extends LinearLayout {

    private static final int SHOW_INITIAL_HEIGHT_DP = 7;
    private static final int SHOW_CONTAINER_SCALE_DURATION = 333;
    private static final int SHOW_CONTAINER_ALPHA_DURATION = 83;
    private static final int SHOW_CONTENT_ALPHA_DELAY = 67;
    private static final int SHOW_CONTENT_ALPHA_DURATION = 83;
    private static final int HIDE_DURATION = 83;

    private final Launcher mLauncher;

    private View mText;
    private View mCloseButton;
    @Nullable
    private Runnable mOnCloseCallback = null;
    private boolean mIsHideAnimationRunning;
    private Runnable mOnCloseCallback;
    private AnimatorSet mShowAnimation;
    private Animator mHideAnimation;

    public DesktopAppSelectView(Context context) {
        this(context, null);
@@ -68,15 +84,17 @@ public class DesktopAppSelectView extends LinearLayout {
        DesktopAppSelectView view = (DesktopAppSelectView) launcher.getLayoutInflater().inflate(
                R.layout.floating_desktop_app_select, launcher.getDragLayer(), false);
        view.setOnCloseClickCallback(onCloseCallback);
        launcher.getDragLayer().addView(view);
        view.show();
        return view;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        findViewById(R.id.close_button).setOnClickListener(v -> {
            if (!mIsHideAnimationRunning) {
        mText = findViewById(R.id.desktop_app_select_text);
        mCloseButton = findViewById(R.id.close_button);
        mCloseButton.setOnClickListener(v -> {
            if (mHideAnimation == null) {
                hide();
                if (mOnCloseCallback != null) {
                    mOnCloseCallback.run();
@@ -85,18 +103,71 @@ public class DesktopAppSelectView extends LinearLayout {
        });
    }

    private void show() {
        mLauncher.getDragLayer().addView(this);

        // Set up initial values
        getBackground().setAlpha(0);
        mText.setAlpha(0);
        mCloseButton.setAlpha(0);
        int initialHeightPx = Utilities.dpToPx(SHOW_INITIAL_HEIGHT_DP);
        int finalHeight = getResources().getDimensionPixelSize(
                R.dimen.desktop_mode_floating_app_select_height);
        float initialScale = initialHeightPx / (float) finalHeight;
        setScaleY(initialScale);
        setPivotY(0);

        // Animate the container
        ValueAnimator containerBackground = ValueAnimator.ofInt(0, 255);
        containerBackground.addUpdateListener(
                animation -> getBackground().setAlpha((Integer) animation.getAnimatedValue()));
        containerBackground.setDuration(SHOW_CONTAINER_ALPHA_DURATION);
        containerBackground.setInterpolator(LINEAR);

        ObjectAnimator containerSize = ObjectAnimator.ofFloat(this, SCALE_Y, 1f);
        containerSize.setDuration(SHOW_CONTAINER_SCALE_DURATION);
        containerSize.setInterpolator(EMPHASIZED_DECELERATE);

        // Animate the contents
        ObjectAnimator textAlpha = ObjectAnimator.ofFloat(mText, ALPHA, 1);
        ObjectAnimator buttonAlpha = ObjectAnimator.ofFloat(mCloseButton, ALPHA, 1);
        AnimatorSet contentAlpha = new AnimatorSet();
        contentAlpha.playTogether(textAlpha, buttonAlpha);
        contentAlpha.setStartDelay(SHOW_CONTENT_ALPHA_DELAY);
        contentAlpha.setDuration(SHOW_CONTENT_ALPHA_DURATION);
        contentAlpha.setInterpolator(LINEAR);

        // Start the animation
        mShowAnimation = new AnimatorSet();
        mShowAnimation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                mShowAnimation = null;
            }
        });
        mShowAnimation.playTogether(containerBackground, containerSize, contentAlpha);
        mShowAnimation.start();
    }

    /**
     * Hide the floating view
     */
    public void hide() {
        if (!mIsHideAnimationRunning) {
            mIsHideAnimationRunning = true;
            animate().alpha(0).setDuration(HIDE_DURATION).setInterpolator(LINEAR).withEndAction(
                    () -> {
                        mLauncher.getDragLayer().removeView(this);
                        mIsHideAnimationRunning = false;
                    });
        if (mShowAnimation != null) {
            mShowAnimation.cancel();
        }
        mHideAnimation = ObjectAnimator.ofFloat(this, ALPHA, 0);
        mHideAnimation.setDuration(HIDE_DURATION).setInterpolator(LINEAR);
        mHideAnimation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                mLauncher.getDragLayer().removeView(DesktopAppSelectView.this);
                mHideAnimation = null;
            }
        });
        mHideAnimation.start();
    }

    /**