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

Commit 222a59e7 authored by Hyunyoung Song's avatar Hyunyoung Song
Browse files

Implement overshoot and squish motion in all apps open

Bug: 187475924
Bug: 183062683
Test: manual

Change-Id: I33b6c647c45ff467c6d49cf3796f92ca366ab3f1
parent b1754bfc
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@
    <dimen name="fastscroll_end_margin">-26dp</dimen>

    <!-- All Apps -->
    <dimen name="all_apps_open_vertical_translate">300dp</dimen>
    <dimen name="all_apps_open_vertical_translate">320dp</dimen>
    <dimen name="all_apps_search_bar_field_height">48dp</dimen>
    <dimen name="all_apps_search_bar_bottom_padding">30dp</dimen>
    <dimen name="all_apps_empty_search_message_top_offset">40dp</dimen>
+2 −5
Original line number Diff line number Diff line
@@ -905,7 +905,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
        } else {
            mOverlayManager.onActivityStopped(this);
        }

        hideKeyboard();
        logStopAndResume(false /* isResume */);
        mAppWidgetHost.setActivityStarted(false);
        NotificationListener.removeNotificationsChangedListener();
@@ -1459,7 +1459,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
                && AbstractFloatingView.getTopOpenView(this) == null;
        boolean isActionMain = Intent.ACTION_MAIN.equals(intent.getAction());
        boolean internalStateHandled = ACTIVITY_TRACKER.handleNewIntent(this, intent);

        hideKeyboard();
        if (isActionMain) {
            if (!internalStateHandled) {
                // In all these cases, only animate if we're already on home
@@ -1481,9 +1481,6 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
                }
            }

            // Handle HOME_INTENT
            hideKeyboard();

            if (mLauncherCallbacks != null) {
                mLauncherCallbacks.onHomeIntent(internalStateHandled);
            }
+37 −5
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.view.WindowInsets;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.annotation.VisibleForTesting;
import androidx.core.graphics.ColorUtils;
import androidx.core.os.BuildCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
@@ -79,10 +80,11 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
        Insettable, OnDeviceProfileChangeListener, OnActivePageChangedListener,
        ScrimView.ScrimDrawingController {

    private static final float FLING_VELOCITY_MULTIPLIER = 1000f;
    public static final float PULL_MULTIPLIER = .02f;
    public static final float FLING_VELOCITY_MULTIPLIER = 2000f;

    // Starts the springs after at least 25% of the animation has passed.
    private static final float FLING_ANIMATION_THRESHOLD = 0.25f;
    public static final float FLING_ANIMATION_THRESHOLD = 0.25f;

    private final Paint mHeaderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

@@ -100,6 +102,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
    private AllAppsPagedView mViewPager;

    protected FloatingHeaderView mHeader;
    private float mHeaderTop;
    private WorkModeSwitch mWorkModeSwitch;


@@ -530,7 +533,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
        return view.getGlobalVisibleRect(new Rect());
    }

    // Used by tests only
    @VisibleForTesting
    public boolean isPersonalTabVisible() {
        return isDescendantViewVisible(R.id.tab_personal);
    }
@@ -582,6 +585,7 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
            mAH[i].padding.top = padding;
            mAH[i].applyPadding();
        }
        mHeaderTop = mHeader.getTop();
    }

    public void setLastSearchQuery(String query) {
@@ -636,14 +640,42 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                if (shouldSpring
                        && valueAnimator.getAnimatedFraction() >= FLING_ANIMATION_THRESHOLD) {
                    absorbSwipeUpVelocity(Math.abs(
                            Math.round(velocity * FLING_VELOCITY_MULTIPLIER)));
                    absorbSwipeUpVelocity(Math.max(100, Math.abs(
                            Math.round(velocity * FLING_VELOCITY_MULTIPLIER))));
                    // calculate the velocity of using the not user controlled interpolator
                    // of when the container reach the end.
                    shouldSpring = false;
                }
            }
        });
    }

    public void onPull(float deltaDistance, float displacement) {
        absorbPullDeltaDistance(PULL_MULTIPLIER * deltaDistance,
                PULL_MULTIPLIER * displacement);
        // ideally, this should be done using EdgeEffect.onPush to create squish effect.
        // However, until such method is available, launcher to simulate the onPush method.
        mHeader.setTranslationY(-.5f * mHeaderTop * deltaDistance);
        getRecyclerViewContainer().setTranslationY(-mHeaderTop * deltaDistance);
    }

    public void onRelease() {
        ValueAnimator anim1 = ValueAnimator.ofFloat(1f, 0f);
        final float floatingHeaderHeight = getFloatingHeaderView().getTranslationY();
        final float recyclerViewHeight = getRecyclerViewContainer().getTranslationY();
        anim1.setDuration(200);
        anim1.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                getFloatingHeaderView().setTranslationY(
                        ((float) valueAnimator.getAnimatedValue()) * floatingHeaderHeight);
                getRecyclerViewContainer().setTranslationY(
                        ((float) valueAnimator.getAnimatedValue()) * recyclerViewHeight);
            }
        });
        anim1.start();
        super.onRelease();
    }
    @Override
    public void getDrawingRect(Rect outRect) {
        super.getDrawingRect(outRect);
+3 −7
Original line number Diff line number Diff line
@@ -17,10 +17,7 @@ package com.android.launcher3.allapps;

import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT;
import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
import static com.android.launcher3.anim.Interpolators.DEACCEL;
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER;
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
@@ -158,9 +155,8 @@ public class AllAppsTransitionController
            return;
        }

        Interpolator interpolator = toState.equals(ALL_APPS)
                ? (config.userControlled ? ACCEL_2 : ACCEL_0_75) :
                (config.userControlled ? DEACCEL_2 : DEACCEL);
        // need to decide depending on the release velocity
        Interpolator interpolator = (config.userControlled ? LINEAR : DEACCEL_1_7);

        Animator anim = createSpringAnimation(mProgress, targetProgress);
        anim.setInterpolator(config.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
+20 −5
Original line number Diff line number Diff line
@@ -56,9 +56,8 @@ public abstract class AbstractStateChangeTouchController

    protected final AnimatorListener mClearStateOnCancelListener =
            newCancelListener(this::clearState);
    private final FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();

    private boolean mNoIntercept;
    private boolean mIsLogContainerSet;
    protected int mStartContainerType;

    protected LauncherState mStartState;
@@ -67,12 +66,14 @@ public abstract class AbstractStateChangeTouchController
    protected AnimatorPlaybackController mCurrentAnimation;
    protected boolean mGoingBetweenStates = true;

    private boolean mNoIntercept;
    private boolean mIsLogContainerSet;
    private float mStartProgress;
    // Ratio of transition process [0, 1] to drag displacement (px)
    private float mProgressMultiplier;
    private float mDisplacementShift;
    private boolean mCanBlockFling;
    private final FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck();
    private boolean mAllAppsOvershootStarted;

    public AbstractStateChangeTouchController(Launcher l, SingleAxisSwipeDetector.Direction dir) {
        mLauncher = l;
@@ -216,8 +217,15 @@ public abstract class AbstractStateChangeTouchController
                    mFlingBlockCheck.blockFling();
                }
            }
            if (mToState == LauncherState.ALL_APPS && !UNSTABLE_SPRINGS.get()) {
                mAllAppsOvershootStarted = true;
                // 1f, value when all apps container hit the top
                mLauncher.getAppsView().onPull(progress - 1f, progress - 1f);
            }

        } else {
            mFlingBlockCheck.onEvent();

        }

        return true;
@@ -325,9 +333,16 @@ public abstract class AbstractStateChangeTouchController
        anim.setFloatValues(startProgress, endProgress);
        updateSwipeCompleteAnimation(anim, duration, targetState, velocity, fling);
        mCurrentAnimation.dispatchOnStart();
        if (fling && targetState == LauncherState.ALL_APPS && !UNSTABLE_SPRINGS.get()) {
        if (targetState == LauncherState.ALL_APPS && !UNSTABLE_SPRINGS.get()) {
            if (mAllAppsOvershootStarted) {

                mLauncher.getAppsView().onRelease();
                mAllAppsOvershootStarted = false;

            } else {
                mLauncher.getAppsView().addSpringFromFlingUpdateListener(anim, velocity);
            }
        }
        anim.start();
    }

Loading