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

Commit ea068967 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add staggered springs animation when swiping up to home." into ub-launcher3-qt-dev

parents 5a93e5d8 c69d1ffd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -27,4 +27,5 @@
    <!-- Swipe up to home related -->
    <dimen name="swipe_up_fling_min_visible_change">18dp</dimen>
    <dimen name="swipe_up_y_overshoot">10dp</dimen>
    <dimen name="swipe_up_max_workspace_trans_y">-80dp</dimen>
</resources>
 No newline at end of file
+15 −1
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.views.FloatingIconView;
import com.android.quickstep.SysUINavigationMode.Mode;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.StaggeredWorkspaceAnim;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -151,8 +152,21 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
            @NonNull
            @Override
            public AnimatorPlaybackController createActivityAnimationToHome() {
                // Return an empty APC here since we have an non-user controlled animation to home.
                long accuracy = 2 * Math.max(dp.widthPx, dp.heightPx);
                return activity.getStateManager().createAnimationToNewWorkspace(NORMAL, accuracy);
                AnimatorSet as = new AnimatorSet();
                as.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationStart(Animator animation) {
                        activity.getStateManager().goToState(NORMAL, false);
                    }
                });
                return AnimatorPlaybackController.wrap(as, accuracy);
            }

            @Override
            public void playAtomicAnimation(float velocity) {
                new StaggeredWorkspaceAnim(activity, workspaceView, velocity).start();
            }
        };
    }
+1 −0
Original line number Diff line number Diff line
@@ -1057,6 +1057,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
                    setStateOnUiThread(target.endState);
                }
            });
            homeAnimFactory.playAtomicAnimation(velocityPxPerMs.y);
            windowAnim.start(velocityPxPerMs);
            mRunningWindowAnim = RunningWindowAnim.wrap(windowAnim);
            mLauncherTransitionController = null;
+154 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.quickstep.util;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.Nullable;
import androidx.dynamicanimation.animation.SpringForce;

import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAnimUtils.ViewProgressProperty;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.anim.SpringObjectAnimator;

import java.util.ArrayList;
import java.util.List;

import static com.android.launcher3.anim.Interpolators.LINEAR;

/**
 * Creates an animation where all the workspace items are moved into their final location,
 * staggered row by row from the bottom up.
 * This is used in conjunction with the swipe up to home animation.
 */
public class StaggeredWorkspaceAnim {

    private static final int APP_CLOSE_ROW_START_DELAY_MS = 16;
    private static final int ALPHA_DURATION_MS = 200;

    private static final float MAX_VELOCITY_PX_PER_S = 22f;

    private static final float DAMPING_RATIO =
            (SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY + SpringForce.DAMPING_RATIO_LOW_BOUNCY) / 2f;
    private static final float STIFFNESS = SpringForce.STIFFNESS_LOW;

    private final float mVelocity;
    private final float mSpringTransY;
    private final View mViewToIgnore;

    private final List<ValueAnimator> mAnimators = new ArrayList<>();

    /**
     * @param floatingViewOriginalView The FloatingIconView's original view.
     */
    public StaggeredWorkspaceAnim(Launcher launcher, @Nullable View floatingViewOriginalView,
            float velocity) {
        mVelocity = velocity;
        // We ignore this view since it's visibility and position is controlled by
        // the FloatingIconView.
        mViewToIgnore = floatingViewOriginalView;

        // Scale the translationY based on the initial velocity to better sync the workspace items
        // with the floating view.
        float transFactor = 0.1f + 0.9f * Math.abs(velocity) / MAX_VELOCITY_PX_PER_S;
        mSpringTransY = transFactor * launcher.getResources()
                .getDimensionPixelSize(R.dimen.swipe_up_max_workspace_trans_y);;

        DeviceProfile grid = launcher.getDeviceProfile();
        ShortcutAndWidgetContainer currentPage = ((CellLayout) launcher.getWorkspace()
                .getChildAt(launcher.getWorkspace().getCurrentPage()))
                .getShortcutsAndWidgets();

        // Hotseat and QSB takes up two additional rows.
        int totalRows = grid.inv.numRows + (grid.isVerticalBarLayout() ? 0 : 2);

        // Set up springs on workspace items.
        for (int i = currentPage.getChildCount() - 1; i >= 0; i--) {
            View child = currentPage.getChildAt(i);
            CellLayout.LayoutParams lp = ((CellLayout.LayoutParams) child.getLayoutParams());
            addStaggeredAnimationForView(child, lp.cellY + lp.cellVSpan, totalRows);
        }

        // Set up springs for the hotseat and qsb.
        if (grid.isVerticalBarLayout()) {
            ViewGroup hotseat = (ViewGroup) launcher.getHotseat().getChildAt(0);
            for (int i = hotseat.getChildCount() - 1; i >= 0; i--) {
                View child = hotseat.getChildAt(i);
                CellLayout.LayoutParams lp = ((CellLayout.LayoutParams) child.getLayoutParams());
                addStaggeredAnimationForView(child, lp.cellY + 1, totalRows);
            }
        } else {
            View hotseat = launcher.getHotseat().getChildAt(0);
            addStaggeredAnimationForView(hotseat, grid.inv.numRows + 1, totalRows);

            View qsb = launcher.findViewById(R.id.search_container_all_apps);
            addStaggeredAnimationForView(qsb, grid.inv.numRows + 2, totalRows);
        }
    }

    /**
     * Starts the animation.
     */
    public void start() {
        for (Animator a : mAnimators) {
            if (a instanceof SpringObjectAnimator) {
                ((SpringObjectAnimator) a).startSpring(1f, mVelocity, null);
            } else {
                a.start();
            }
        }
    }

    /**
     * Adds an alpha/trans animator for {@param v}, with a start delay based on the view's row.
     *
     * @param v A view on the workspace.
     * @param row The bottom-most row that contains the view.
     * @param totalRows Total number of rows.
     */
    private void addStaggeredAnimationForView(View v, int row, int totalRows) {
        if (v == mViewToIgnore) {
            return;
        }

        // Invert the rows, because we stagger starting from the bottom of the screen.
        int invertedRow = totalRows - row;
        // Add 1 to the inverted row so that the bottom most row has a start delay.
        long startDelay = (long) ((invertedRow + 1) * APP_CLOSE_ROW_START_DELAY_MS);

        v.setTranslationY(mSpringTransY);
        SpringObjectAnimator springTransY = new SpringObjectAnimator<>(
                new ViewProgressProperty(v, View.TRANSLATION_Y), "staggeredSpringTransY", 1f,
                DAMPING_RATIO, STIFFNESS, mSpringTransY, 0);
        springTransY.setStartDelay(startDelay);
        mAnimators.add(springTransY);

        v.setAlpha(0);
        ObjectAnimator alpha = ObjectAnimator.ofFloat(v, View.ALPHA, 0f, 1f);
        alpha.setInterpolator(LINEAR);
        alpha.setDuration(ALPHA_DURATION_MS);
        alpha.setStartDelay(startDelay);
        mAnimators.add(alpha);
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -143,5 +143,9 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
        @NonNull RectF getWindowTargetRect();

        @NonNull AnimatorPlaybackController createActivityAnimationToHome();

        default void playAtomicAnimation(float velocity) {
            // No-op
        }
    }
}
Loading