Merge "Improve quick switch from home by tracking both x and y motion" into ub-launcher3-qt-future-dev
This commit is contained in:
@@ -24,4 +24,8 @@ public class ShelfPeekAnim {
|
||||
|
||||
public enum ShelfAnimState {
|
||||
}
|
||||
|
||||
public boolean isPeeking() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+26
-1
@@ -21,8 +21,15 @@ import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_HOTSEAT_SCALE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_HOTSEAT_TRANSLATE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS;
|
||||
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||
import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch;
|
||||
import static com.android.quickstep.TaskViewUtils.getRecentsWindowAnimator;
|
||||
|
||||
@@ -40,6 +47,7 @@ import androidx.annotation.Nullable;
|
||||
import com.android.launcher3.LauncherState.ScaleAndTranslation;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.AnimatorSetBuilder;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.anim.SpringAnimationBuilder;
|
||||
import com.android.quickstep.util.ClipAnimationHelper;
|
||||
@@ -56,6 +64,9 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti
|
||||
public static final int INDEX_SHELF_ANIM = 0;
|
||||
public static final int INDEX_RECENTS_FADE_ANIM = 1;
|
||||
public static final int INDEX_RECENTS_TRANSLATE_X_ANIM = 2;
|
||||
public static final int INDEX_PAUSE_TO_OVERVIEW_ANIM = 3;
|
||||
|
||||
public static final long ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW = 300;
|
||||
|
||||
public LauncherAppTransitionManagerImpl(Context context) {
|
||||
super(context);
|
||||
@@ -144,7 +155,7 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti
|
||||
|
||||
@Override
|
||||
public int getStateElementAnimationsCount() {
|
||||
return 3;
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -190,6 +201,20 @@ public final class LauncherAppTransitionManagerImpl extends QuickstepAppTransiti
|
||||
.setStiffness(250)
|
||||
.setValues(values)
|
||||
.build(mLauncher);
|
||||
case INDEX_PAUSE_TO_OVERVIEW_ANIM: {
|
||||
AnimatorSetBuilder builder = new AnimatorSetBuilder();
|
||||
builder.setInterpolator(ANIM_VERTICAL_PROGRESS, OVERSHOOT_1_2);
|
||||
builder.setInterpolator(ANIM_ALL_APPS_FADE, DEACCEL_3);
|
||||
if ((OVERVIEW.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) {
|
||||
builder.setInterpolator(ANIM_HOTSEAT_SCALE, OVERSHOOT_1_2);
|
||||
builder.setInterpolator(ANIM_HOTSEAT_TRANSLATE, OVERSHOOT_1_2);
|
||||
}
|
||||
LauncherStateManager stateManager = mLauncher.getStateManager();
|
||||
return stateManager.createAtomicAnimation(
|
||||
stateManager.getCurrentStableState(), OVERVIEW, builder,
|
||||
ANIM_ALL, ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW);
|
||||
}
|
||||
|
||||
default:
|
||||
return super.createStateElementAnimation(index, values);
|
||||
}
|
||||
|
||||
+3
-3
@@ -28,17 +28,17 @@ import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.LauncherStateManager.StateHandler;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.graphics.RotationMode;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.FlingAndHoldTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.LandscapeEdgeSwipeController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.NavBarToHomeTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.NoButtonQuickSwitchTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.OverviewToAllAppsTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.PortraitStatesTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.StatusBarTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.QuickSwitchTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.StatusBarTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController;
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.TransposedQuickSwitchTouchController;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
@@ -145,7 +145,7 @@ public abstract class RecentsUiFactory {
|
||||
ArrayList<TouchController> list = new ArrayList<>();
|
||||
list.add(launcher.getDragController());
|
||||
if (mode == NO_BUTTON) {
|
||||
list.add(new QuickSwitchTouchController(launcher));
|
||||
list.add(new NoButtonQuickSwitchTouchController(launcher));
|
||||
list.add(new NavBarToHomeTouchController(launcher));
|
||||
list.add(new FlingAndHoldTouchController(launcher));
|
||||
} else {
|
||||
|
||||
+2
@@ -22,6 +22,7 @@ import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_FADE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_SCALE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_FADE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_SCALE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_TRANSLATE;
|
||||
@@ -205,6 +206,7 @@ public class OverviewState extends LauncherState {
|
||||
builder.setInterpolator(ANIM_WORKSPACE_FADE, OVERSHOOT_1_2);
|
||||
builder.setInterpolator(ANIM_OVERVIEW_SCALE, OVERSHOOT_1_2);
|
||||
builder.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, OVERSHOOT_1_7);
|
||||
builder.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, OVERSHOOT_1_7);
|
||||
builder.setInterpolator(ANIM_OVERVIEW_FADE, OVERSHOOT_1_2);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-16
@@ -16,25 +16,20 @@
|
||||
|
||||
package com.android.launcher3.uioverrides.touchcontrollers;
|
||||
|
||||
import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_PAUSE_TO_OVERVIEW_ANIM;
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW_PEEK;
|
||||
import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
|
||||
import static com.android.launcher3.LauncherStateManager.ATOMIC_OVERVIEW_PEEK_COMPONENT;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_HEADER_FADE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_HOTSEAT_SCALE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_HOTSEAT_TRANSLATE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_FADE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_SCALE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_TRANSLATE;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
|
||||
import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
|
||||
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||
|
||||
@@ -46,6 +41,7 @@ import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppTransitionManagerImpl;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.anim.AnimatorSetBuilder;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
@@ -79,7 +75,7 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController {
|
||||
|
||||
@Override
|
||||
protected long getAtomicDuration() {
|
||||
return 300;
|
||||
return LauncherAppTransitionManagerImpl.ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -179,15 +175,8 @@ public class FlingAndHoldTouchController extends PortraitStatesTouchController {
|
||||
mPeekAnim.cancel();
|
||||
}
|
||||
|
||||
AnimatorSetBuilder builder = new AnimatorSetBuilder();
|
||||
builder.setInterpolator(ANIM_VERTICAL_PROGRESS, OVERSHOOT_1_2);
|
||||
builder.setInterpolator(ANIM_ALL_APPS_FADE, DEACCEL_3);
|
||||
if ((OVERVIEW.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) {
|
||||
builder.setInterpolator(ANIM_HOTSEAT_SCALE, OVERSHOOT_1_2);
|
||||
builder.setInterpolator(ANIM_HOTSEAT_TRANSLATE, OVERSHOOT_1_2);
|
||||
}
|
||||
AnimatorSet overviewAnim = mLauncher.getStateManager().createAtomicAnimation(
|
||||
NORMAL, OVERVIEW, builder, ANIM_ALL, ATOMIC_DURATION);
|
||||
Animator overviewAnim = mLauncher.getAppTransitionManager().createStateElementAnimation(
|
||||
INDEX_PAUSE_TO_OVERVIEW_ANIM);
|
||||
overviewAnim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
|
||||
+462
@@ -0,0 +1,462 @@
|
||||
/*
|
||||
* 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.launcher3.uioverrides.touchcontrollers;
|
||||
|
||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||
import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_PAUSE_TO_OVERVIEW_ANIM;
|
||||
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.LauncherState.QUICK_SWITCH;
|
||||
import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
|
||||
import static com.android.launcher3.anim.AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_ALL_APPS_FADE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_VERTICAL_PROGRESS;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_FADE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_WORKSPACE_TRANSLATE;
|
||||
import static com.android.launcher3.anim.AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_0_75;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_5;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
|
||||
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_RIGHT;
|
||||
import static com.android.launcher3.touch.BothAxesSwipeDetector.DIRECTION_UP;
|
||||
import static com.android.launcher3.util.DefaultDisplay.getSingleFrameMs;
|
||||
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
||||
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.CANCEL;
|
||||
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.HIDE;
|
||||
import static com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState.PEEK;
|
||||
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
||||
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.graphics.PointF;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.LauncherStateManager;
|
||||
import com.android.launcher3.LauncherStateManager.AnimationConfig;
|
||||
import com.android.launcher3.QuickstepAppTransitionManagerImpl;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.allapps.AllAppsTransitionController;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.AnimatorSetBuilder;
|
||||
import com.android.launcher3.graphics.OverviewScrim;
|
||||
import com.android.launcher3.touch.BaseSwipeDetector;
|
||||
import com.android.launcher3.touch.BothAxesSwipeDetector;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
import com.android.launcher3.util.VibratorWrapper;
|
||||
import com.android.quickstep.OverviewInteractionState;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.MotionPauseDetector;
|
||||
import com.android.quickstep.util.ShelfPeekAnim;
|
||||
import com.android.quickstep.util.ShelfPeekAnim.ShelfAnimState;
|
||||
import com.android.quickstep.util.StaggeredWorkspaceAnim;
|
||||
import com.android.quickstep.views.LauncherRecentsView;
|
||||
|
||||
/**
|
||||
* Handles quick switching to a recent task from the home screen. To give as much flexibility to
|
||||
* the user as possible, also handles swipe up and hold to go to overview and swiping back home.
|
||||
*/
|
||||
public class NoButtonQuickSwitchTouchController implements TouchController,
|
||||
BothAxesSwipeDetector.Listener, MotionPauseDetector.OnMotionPauseListener {
|
||||
|
||||
/** The minimum progress of the scale/translationY animation until drag end. */
|
||||
private static final float Y_ANIM_MIN_PROGRESS = 0.15f;
|
||||
private static final Interpolator FADE_OUT_INTERPOLATOR = DEACCEL_5;
|
||||
private static final Interpolator TRANSLATE_OUT_INTERPOLATOR = ACCEL_0_75;
|
||||
private static final Interpolator SCALE_DOWN_INTERPOLATOR = DEACCEL;
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final BothAxesSwipeDetector mSwipeDetector;
|
||||
private final float mXRange;
|
||||
private final float mYRange;
|
||||
private final MotionPauseDetector mMotionPauseDetector;
|
||||
private final float mMotionPauseMinDisplacement;
|
||||
|
||||
private boolean mNoIntercept;
|
||||
private LauncherState mStartState;
|
||||
|
||||
private ShelfPeekAnim mShelfPeekAnim;
|
||||
private boolean mIsHomeScreenVisible = true;
|
||||
|
||||
// As we drag, we control 3 animations: one to get non-overview components out of the way,
|
||||
// and the other two to set overview properties based on x and y progress.
|
||||
private AnimatorPlaybackController mNonOverviewAnim;
|
||||
private AnimatorPlaybackController mXOverviewAnim;
|
||||
private AnimatorPlaybackController mYOverviewAnim;
|
||||
|
||||
public NoButtonQuickSwitchTouchController(Launcher launcher) {
|
||||
mLauncher = launcher;
|
||||
mSwipeDetector = new BothAxesSwipeDetector(mLauncher, this);
|
||||
mXRange = mLauncher.getDeviceProfile().widthPx / 2f;
|
||||
mYRange = LayoutUtils.getShelfTrackingDistance(mLauncher, mLauncher.getDeviceProfile());
|
||||
mMotionPauseDetector = new MotionPauseDetector(mLauncher);
|
||||
mMotionPauseMinDisplacement = mLauncher.getResources().getDimension(
|
||||
R.dimen.motion_pause_detector_min_displacement_from_app);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
|
||||
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
mNoIntercept = !canInterceptTouch(ev);
|
||||
if (mNoIntercept) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only detect horizontal swipe for intercept, then we will allow swipe up as well.
|
||||
mSwipeDetector.setDetectableScrollConditions(DIRECTION_RIGHT,
|
||||
false /* ignoreSlopWhenSettling */);
|
||||
}
|
||||
|
||||
if (mNoIntercept) {
|
||||
return false;
|
||||
}
|
||||
|
||||
onControllerTouchEvent(ev);
|
||||
return mSwipeDetector.isDraggingOrSettling();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onControllerTouchEvent(MotionEvent ev) {
|
||||
return mSwipeDetector.onTouchEvent(ev);
|
||||
}
|
||||
|
||||
private boolean canInterceptTouch(MotionEvent ev) {
|
||||
if (!mLauncher.isInState(LauncherState.NORMAL)) {
|
||||
return false;
|
||||
}
|
||||
if ((ev.getEdgeFlags() & Utilities.EDGE_NAV_BAR) == 0) {
|
||||
return false;
|
||||
}
|
||||
int stateFlags = OverviewInteractionState.INSTANCE.get(mLauncher).getSystemUiStateFlags();
|
||||
if ((stateFlags & SYSUI_STATE_OVERVIEW_DISABLED) != 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragStart(boolean start) {
|
||||
mMotionPauseDetector.clear();
|
||||
if (start) {
|
||||
mShelfPeekAnim = ((QuickstepAppTransitionManagerImpl) mLauncher
|
||||
.getAppTransitionManager()).getShelfPeekAnim();
|
||||
|
||||
mStartState = mLauncher.getStateManager().getState();
|
||||
|
||||
mMotionPauseDetector.setOnMotionPauseListener(this);
|
||||
|
||||
// We have detected horizontal drag start, now allow swipe up as well.
|
||||
mSwipeDetector.setDetectableScrollConditions(DIRECTION_RIGHT | DIRECTION_UP,
|
||||
false /* ignoreSlopWhenSettling */);
|
||||
|
||||
setupAnimators();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMotionPauseChanged(boolean isPaused) {
|
||||
ShelfAnimState shelfState = isPaused ? PEEK : HIDE;
|
||||
if (shelfState == PEEK) {
|
||||
// Some shelf elements (e.g. qsb) were hidden, but we need them visible when peeking.
|
||||
AnimatorSetBuilder builder = new AnimatorSetBuilder();
|
||||
AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
|
||||
allAppsController.setAlphas(NORMAL.getVisibleElements(mLauncher),
|
||||
new AnimationConfig(), builder);
|
||||
builder.build().setDuration(0).start();
|
||||
|
||||
if ((OVERVIEW.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) {
|
||||
// Hotseat was hidden, but we need it visible when peeking.
|
||||
mLauncher.getHotseat().setAlpha(1);
|
||||
}
|
||||
}
|
||||
mShelfPeekAnim.setShelfState(shelfState, ShelfPeekAnim.INTERPOLATOR,
|
||||
ShelfPeekAnim.DURATION);
|
||||
VibratorWrapper.INSTANCE.get(mLauncher).vibrate(OVERVIEW_HAPTIC);
|
||||
}
|
||||
|
||||
private void setupAnimators() {
|
||||
// Animate the non-overview components (e.g. workspace, shelf) out of the way.
|
||||
AnimatorSetBuilder nonOverviewBuilder = new AnimatorSetBuilder();
|
||||
nonOverviewBuilder.setInterpolator(ANIM_WORKSPACE_FADE, FADE_OUT_INTERPOLATOR);
|
||||
nonOverviewBuilder.setInterpolator(ANIM_ALL_APPS_FADE, FADE_OUT_INTERPOLATOR);
|
||||
nonOverviewBuilder.setInterpolator(ANIM_WORKSPACE_TRANSLATE, TRANSLATE_OUT_INTERPOLATOR);
|
||||
nonOverviewBuilder.setInterpolator(ANIM_VERTICAL_PROGRESS, TRANSLATE_OUT_INTERPOLATOR);
|
||||
updateNonOverviewAnim(QUICK_SWITCH, nonOverviewBuilder, ANIM_ALL);
|
||||
mNonOverviewAnim.dispatchOnStart();
|
||||
|
||||
setupOverviewAnimators();
|
||||
}
|
||||
|
||||
/** Create state animation to control non-overview components. */
|
||||
private void updateNonOverviewAnim(LauncherState toState, AnimatorSetBuilder builder,
|
||||
@LauncherStateManager.AnimationComponents int animComponents) {
|
||||
builder.addFlag(FLAG_DONT_ANIMATE_OVERVIEW);
|
||||
long accuracy = (long) (Math.max(mXRange, mYRange) * 2);
|
||||
mNonOverviewAnim = mLauncher.getStateManager().createAnimationToNewWorkspace(toState,
|
||||
builder, accuracy, this::clearState, animComponents);
|
||||
}
|
||||
|
||||
private void setupOverviewAnimators() {
|
||||
final LauncherState fromState = QUICK_SWITCH;
|
||||
final LauncherState toState = OVERVIEW;
|
||||
LauncherState.ScaleAndTranslation fromScaleAndTranslation = fromState
|
||||
.getOverviewScaleAndTranslation(mLauncher);
|
||||
LauncherState.ScaleAndTranslation toScaleAndTranslation = toState
|
||||
.getOverviewScaleAndTranslation(mLauncher);
|
||||
// Update RecentView's translationX to have it start offscreen.
|
||||
LauncherRecentsView recentsView = mLauncher.getOverviewPanel();
|
||||
float startScale = Utilities.mapRange(
|
||||
SCALE_DOWN_INTERPOLATOR.getInterpolation(Y_ANIM_MIN_PROGRESS),
|
||||
fromScaleAndTranslation.scale,
|
||||
toScaleAndTranslation.scale);
|
||||
fromScaleAndTranslation.translationX = recentsView.getOffscreenTranslationX(startScale);
|
||||
|
||||
// Set RecentView's initial properties.
|
||||
recentsView.setScaleX(fromScaleAndTranslation.scale);
|
||||
recentsView.setScaleY(fromScaleAndTranslation.scale);
|
||||
recentsView.setTranslationX(fromScaleAndTranslation.translationX);
|
||||
recentsView.setTranslationY(fromScaleAndTranslation.translationY);
|
||||
recentsView.setContentAlpha(1);
|
||||
|
||||
// As we drag right, animate the following properties:
|
||||
// - RecentsView translationX
|
||||
// - OverviewScrim
|
||||
AnimatorSet xOverviewAnim = new AnimatorSet();
|
||||
xOverviewAnim.play(ObjectAnimator.ofFloat(recentsView, View.TRANSLATION_X,
|
||||
toScaleAndTranslation.translationX));
|
||||
xOverviewAnim.play(ObjectAnimator.ofFloat(
|
||||
mLauncher.getDragLayer().getOverviewScrim(), OverviewScrim.SCRIM_PROGRESS,
|
||||
toState.getOverviewScrimAlpha(mLauncher)));
|
||||
long xAccuracy = (long) (mXRange * 2);
|
||||
xOverviewAnim.setDuration(xAccuracy);
|
||||
mXOverviewAnim = AnimatorPlaybackController.wrap(xOverviewAnim, xAccuracy);
|
||||
mXOverviewAnim.dispatchOnStart();
|
||||
|
||||
// As we drag up, animate the following properties:
|
||||
// - RecentsView translationY
|
||||
// - RecentsView scale
|
||||
// - RecentsView fullscreenProgress
|
||||
AnimatorSet yAnimation = new AnimatorSet();
|
||||
Animator translateYAnim = ObjectAnimator.ofFloat(recentsView, View.TRANSLATION_Y,
|
||||
toScaleAndTranslation.translationY);
|
||||
Animator scaleAnim = ObjectAnimator.ofFloat(recentsView, SCALE_PROPERTY,
|
||||
toScaleAndTranslation.scale);
|
||||
Animator fullscreenProgressAnim = ObjectAnimator.ofFloat(recentsView, FULLSCREEN_PROGRESS,
|
||||
fromState.getOverviewFullscreenProgress(), toState.getOverviewFullscreenProgress());
|
||||
scaleAnim.setInterpolator(SCALE_DOWN_INTERPOLATOR);
|
||||
fullscreenProgressAnim.setInterpolator(SCALE_DOWN_INTERPOLATOR);
|
||||
yAnimation.play(translateYAnim);
|
||||
yAnimation.play(scaleAnim);
|
||||
yAnimation.play(fullscreenProgressAnim);
|
||||
long yAccuracy = (long) (mYRange * 2);
|
||||
yAnimation.setDuration(yAccuracy);
|
||||
mYOverviewAnim = AnimatorPlaybackController.wrap(yAnimation, yAccuracy);
|
||||
mYOverviewAnim.dispatchOnStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDrag(PointF displacement, MotionEvent ev) {
|
||||
float xProgress = Math.max(0, displacement.x) / mXRange;
|
||||
float yProgress = Math.max(0, -displacement.y) / mYRange;
|
||||
yProgress = Utilities.mapRange(yProgress, Y_ANIM_MIN_PROGRESS, 1f);
|
||||
|
||||
boolean wasHomeScreenVisible = mIsHomeScreenVisible;
|
||||
if (wasHomeScreenVisible && mNonOverviewAnim != null) {
|
||||
mNonOverviewAnim.setPlayFraction(xProgress);
|
||||
}
|
||||
mIsHomeScreenVisible = FADE_OUT_INTERPOLATOR.getInterpolation(xProgress)
|
||||
<= 1 - ALPHA_CUTOFF_THRESHOLD;
|
||||
|
||||
if (wasHomeScreenVisible && !mIsHomeScreenVisible) {
|
||||
// Get the shelf all the way offscreen so it pops up when we decide to peek it.
|
||||
mShelfPeekAnim.setShelfState(HIDE, LINEAR, 0);
|
||||
}
|
||||
|
||||
// Only allow motion pause if the home screen is invisible, since some
|
||||
// home screen elements will appear in the shelf on motion pause.
|
||||
mMotionPauseDetector.setDisallowPause(mIsHomeScreenVisible
|
||||
|| -displacement.y < mMotionPauseMinDisplacement);
|
||||
mMotionPauseDetector.addPosition(displacement.y, ev.getEventTime());
|
||||
|
||||
if (mIsHomeScreenVisible) {
|
||||
// Cancel the shelf anim so it doesn't clobber mNonOverviewAnim.
|
||||
mShelfPeekAnim.setShelfState(CANCEL, LINEAR, 0);
|
||||
}
|
||||
|
||||
if (mXOverviewAnim != null) {
|
||||
mXOverviewAnim.setPlayFraction(xProgress);
|
||||
}
|
||||
if (mYOverviewAnim != null) {
|
||||
mYOverviewAnim.setPlayFraction(yProgress);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragEnd(PointF velocity) {
|
||||
boolean horizontalFling = mSwipeDetector.isFling(velocity.x);
|
||||
boolean verticalFling = mSwipeDetector.isFling(velocity.y);
|
||||
boolean noFling = !horizontalFling && !verticalFling;
|
||||
int logAction = noFling ? Touch.SWIPE : Touch.FLING;
|
||||
if (mMotionPauseDetector.isPaused() && noFling) {
|
||||
cancelAnimations();
|
||||
|
||||
Animator overviewAnim = mLauncher.getAppTransitionManager().createStateElementAnimation(
|
||||
INDEX_PAUSE_TO_OVERVIEW_ANIM);
|
||||
overviewAnim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
onAnimationToStateCompleted(OVERVIEW, logAction);
|
||||
}
|
||||
});
|
||||
overviewAnim.start();
|
||||
return;
|
||||
}
|
||||
|
||||
final LauncherState targetState;
|
||||
if (horizontalFling && verticalFling) {
|
||||
// Flinging left and up, left and down, or right and up all go back home.
|
||||
// Only flinging right and down goes to quick switch.
|
||||
targetState = velocity.x < 0 || velocity.y < 0 ? NORMAL : QUICK_SWITCH;
|
||||
} else if (horizontalFling) {
|
||||
targetState = velocity.x > 0 ? QUICK_SWITCH : NORMAL;
|
||||
} else if (verticalFling) {
|
||||
targetState = velocity.y > 0 ? QUICK_SWITCH : NORMAL;
|
||||
} else {
|
||||
// If user isn't flinging, just snap to the closest state based on x progress.
|
||||
boolean passedHorizontalThreshold = mXOverviewAnim.getInterpolatedProgress() > 0.5f;
|
||||
targetState = passedHorizontalThreshold ? QUICK_SWITCH : NORMAL;
|
||||
}
|
||||
|
||||
// Animate the various components to the target state.
|
||||
|
||||
float xProgress = mXOverviewAnim.getProgressFraction();
|
||||
float startXProgress = Utilities.boundToRange(xProgress
|
||||
+ velocity.x * getSingleFrameMs(mLauncher) / mXRange, 0f, 1f);
|
||||
final float endXProgress = targetState == NORMAL ? 0 : 1;
|
||||
long xDuration = BaseSwipeDetector.calculateDuration(velocity.x,
|
||||
Math.abs(endXProgress - startXProgress));
|
||||
ValueAnimator xOverviewAnim = mXOverviewAnim.getAnimationPlayer();
|
||||
xOverviewAnim.setFloatValues(startXProgress, endXProgress);
|
||||
xOverviewAnim.setDuration(xDuration)
|
||||
.setInterpolator(scrollInterpolatorForVelocity(velocity.x));
|
||||
mXOverviewAnim.dispatchOnStartWithVelocity(endXProgress, velocity.x);
|
||||
|
||||
boolean flingUpToNormal = verticalFling && velocity.y < 0 && targetState == NORMAL;
|
||||
|
||||
float yProgress = mYOverviewAnim.getProgressFraction();
|
||||
float startYProgress = Utilities.boundToRange(yProgress
|
||||
- velocity.y * getSingleFrameMs(mLauncher) / mYRange, 0f, 1f);
|
||||
final float endYProgress;
|
||||
if (flingUpToNormal) {
|
||||
endYProgress = 1;
|
||||
} else if (targetState == NORMAL) {
|
||||
// Keep overview at its current scale/translationY as it slides off the screen.
|
||||
endYProgress = startYProgress;
|
||||
} else {
|
||||
endYProgress = 0;
|
||||
}
|
||||
long yDuration = BaseSwipeDetector.calculateDuration(velocity.y,
|
||||
Math.abs(endYProgress - startYProgress));
|
||||
ValueAnimator yOverviewAnim = mYOverviewAnim.getAnimationPlayer();
|
||||
yOverviewAnim.setFloatValues(startYProgress, endYProgress);
|
||||
yOverviewAnim.setDuration(yDuration);
|
||||
mYOverviewAnim.dispatchOnStartWithVelocity(endYProgress, velocity.y);
|
||||
|
||||
ValueAnimator nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
|
||||
if (flingUpToNormal && !mIsHomeScreenVisible) {
|
||||
// We are flinging to home while workspace is invisible, run the same staggered
|
||||
// animation as from an app.
|
||||
// Update mNonOverviewAnim to do nothing so it doesn't interfere.
|
||||
updateNonOverviewAnim(targetState, new AnimatorSetBuilder(), 0 /* animComponents */);
|
||||
nonOverviewAnim = mNonOverviewAnim.getAnimationPlayer();
|
||||
|
||||
new StaggeredWorkspaceAnim(mLauncher, null, velocity.y,
|
||||
false /* animateOverviewScrim */).start();
|
||||
} else {
|
||||
boolean canceled = targetState == NORMAL;
|
||||
if (canceled) {
|
||||
// Let the state manager know that the animation didn't go to the target state,
|
||||
// but don't clean up yet (we already clean up when the animation completes).
|
||||
mNonOverviewAnim.dispatchOnCancelWithoutCancelRunnable();
|
||||
}
|
||||
float startProgress = mNonOverviewAnim.getProgressFraction();
|
||||
float endProgress = canceled ? 0 : 1;
|
||||
nonOverviewAnim.setFloatValues(startProgress, endProgress);
|
||||
mNonOverviewAnim.dispatchOnStartWithVelocity(endProgress,
|
||||
horizontalFling ? velocity.x : velocity.y);
|
||||
}
|
||||
|
||||
nonOverviewAnim.setDuration(Math.max(xDuration, yDuration));
|
||||
mNonOverviewAnim.setEndAction(() -> onAnimationToStateCompleted(targetState, logAction));
|
||||
|
||||
cancelAnimations();
|
||||
xOverviewAnim.start();
|
||||
yOverviewAnim.start();
|
||||
nonOverviewAnim.start();
|
||||
}
|
||||
|
||||
private void onAnimationToStateCompleted(LauncherState targetState, int logAction) {
|
||||
mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
|
||||
getDirectionForLog(), mSwipeDetector.getDownX(), mSwipeDetector.getDownY(),
|
||||
LauncherLogProto.ContainerType.NAVBAR,
|
||||
mStartState.containerType,
|
||||
targetState.containerType,
|
||||
mLauncher.getWorkspace().getCurrentPage());
|
||||
mLauncher.getStateManager().goToState(targetState, false, this::clearState);
|
||||
}
|
||||
|
||||
private int getDirectionForLog() {
|
||||
return Utilities.isRtl(mLauncher.getResources()) ? Direction.LEFT : Direction.RIGHT;
|
||||
}
|
||||
|
||||
private void cancelAnimations() {
|
||||
if (mNonOverviewAnim != null) {
|
||||
mNonOverviewAnim.getAnimationPlayer().cancel();
|
||||
}
|
||||
if (mXOverviewAnim != null) {
|
||||
mXOverviewAnim.getAnimationPlayer().cancel();
|
||||
}
|
||||
if (mYOverviewAnim != null) {
|
||||
mYOverviewAnim.getAnimationPlayer().cancel();
|
||||
}
|
||||
mShelfPeekAnim.setShelfState(ShelfAnimState.CANCEL, LINEAR, 0);
|
||||
mMotionPauseDetector.clear();
|
||||
}
|
||||
|
||||
private void clearState() {
|
||||
cancelAnimations();
|
||||
mNonOverviewAnim = null;
|
||||
mXOverviewAnim = null;
|
||||
mYOverviewAnim = null;
|
||||
mIsHomeScreenVisible = true;
|
||||
mSwipeDetector.finishedScrolling();
|
||||
}
|
||||
}
|
||||
+2
-15
@@ -24,7 +24,6 @@ import static com.android.launcher3.LauncherAppTransitionManagerImpl.INDEX_SHELF
|
||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||
@@ -53,11 +52,9 @@ import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.LauncherInitListenerEx;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.LauncherStateManager;
|
||||
import com.android.launcher3.QuickstepAppTransitionManagerImpl;
|
||||
import com.android.launcher3.allapps.DiscoveryBounce;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.AnimatorSetBuilder;
|
||||
import com.android.launcher3.userevent.nano.LauncherLogProto;
|
||||
import com.android.launcher3.views.FloatingIconView;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
@@ -169,18 +166,8 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
|
||||
|
||||
@Override
|
||||
public void playAtomicAnimation(float velocity) {
|
||||
// Setup workspace with 0 duration to prepare for our staggered animation.
|
||||
LauncherStateManager stateManager = activity.getStateManager();
|
||||
AnimatorSetBuilder builder = new AnimatorSetBuilder();
|
||||
// setRecentsAttachedToAppWindow() will animate recents out.
|
||||
builder.addFlag(AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW);
|
||||
stateManager.createAtomicAnimation(BACKGROUND_APP, NORMAL, builder, ANIM_ALL, 0);
|
||||
builder.build().start();
|
||||
|
||||
// Stop scrolling so that it doesn't interfere with the translation offscreen.
|
||||
recentsView.getScroller().forceFinished(true);
|
||||
|
||||
new StaggeredWorkspaceAnim(activity, workspaceView, velocity).start();
|
||||
new StaggeredWorkspaceAnim(activity, workspaceView, velocity,
|
||||
true /* animateOverviewScrim */).start();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.android.launcher3.uioverrides.states.OverviewState;
|
||||
/**
|
||||
* Animates the shelf between states HIDE, PEEK, and OVERVIEW.
|
||||
*/
|
||||
|
||||
public class ShelfPeekAnim {
|
||||
|
||||
public static final Interpolator INTERPOLATOR = OVERSHOOT_1_2;
|
||||
|
||||
+25
-5
@@ -18,6 +18,7 @@ package com.android.quickstep.util;
|
||||
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherStateManager.ANIM_ALL;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
|
||||
import android.animation.Animator;
|
||||
@@ -29,11 +30,11 @@ import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.CellLayout;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.LauncherStateManager;
|
||||
import com.android.launcher3.LauncherStateManager.AnimationConfig;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.ShortcutAndWidgetContainer;
|
||||
@@ -41,9 +42,9 @@ import com.android.launcher3.Workspace;
|
||||
import com.android.launcher3.anim.AnimatorSetBuilder;
|
||||
import com.android.launcher3.anim.PropertySetter;
|
||||
import com.android.launcher3.anim.SpringObjectAnimator;
|
||||
import com.android.launcher3.folder.FolderIcon;
|
||||
import com.android.launcher3.graphics.OverviewScrim;
|
||||
import com.android.launcher3.views.IconLabelDotView;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -75,7 +76,9 @@ public class StaggeredWorkspaceAnim {
|
||||
* @param floatingViewOriginalView The FloatingIconView's original view.
|
||||
*/
|
||||
public StaggeredWorkspaceAnim(Launcher launcher, @Nullable View floatingViewOriginalView,
|
||||
float velocity) {
|
||||
float velocity, boolean animateOverviewScrim) {
|
||||
prepareToAnimate(launcher);
|
||||
|
||||
mVelocity = velocity;
|
||||
mOriginalView = floatingViewOriginalView;
|
||||
|
||||
@@ -133,8 +136,10 @@ public class StaggeredWorkspaceAnim {
|
||||
addStaggeredAnimationForView(qsb, grid.inv.numRows + 2, totalRows);
|
||||
}
|
||||
|
||||
addScrimAnimationForState(launcher, BACKGROUND_APP, 0);
|
||||
addScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS);
|
||||
if (animateOverviewScrim) {
|
||||
addScrimAnimationForState(launcher, BACKGROUND_APP, 0);
|
||||
addScrimAnimationForState(launcher, NORMAL, ALPHA_DURATION_MS);
|
||||
}
|
||||
|
||||
AnimatorListener resetClipListener = new AnimatorListenerAdapter() {
|
||||
int numAnimations = mAnimators.size();
|
||||
@@ -160,6 +165,21 @@ public class StaggeredWorkspaceAnim {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup workspace with 0 duration to prepare for our staggered animation.
|
||||
*/
|
||||
private void prepareToAnimate(Launcher launcher) {
|
||||
LauncherStateManager stateManager = launcher.getStateManager();
|
||||
AnimatorSetBuilder builder = new AnimatorSetBuilder();
|
||||
// setRecentsAttachedToAppWindow() will animate recents out.
|
||||
builder.addFlag(AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW);
|
||||
stateManager.createAtomicAnimation(BACKGROUND_APP, NORMAL, builder, ANIM_ALL, 0);
|
||||
builder.build().start();
|
||||
|
||||
// Stop scrolling so that it doesn't interfere with the translation offscreen.
|
||||
launcher.<RecentsView>getOverviewPanel().getScroller().forceFinished(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the animation.
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.quickstep.views;
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
|
||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.LauncherState.QUICK_SWITCH;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_2;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
@@ -35,6 +36,8 @@ import android.util.AttributeSet;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.QuickstepAppTransitionManagerImpl;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
@@ -44,6 +47,7 @@ import com.android.quickstep.SysUINavigationMode;
|
||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||
import com.android.quickstep.SysUINavigationMode.NavigationModeChangeListener;
|
||||
import com.android.quickstep.util.LayoutUtils;
|
||||
import com.android.quickstep.util.ShelfPeekAnim;
|
||||
|
||||
/**
|
||||
* Scrim used for all-apps and shelf in Overview
|
||||
@@ -193,8 +197,12 @@ public class ShelfScrimView extends ScrimView implements NavigationModeChangeLis
|
||||
if (mProgress >= 1) {
|
||||
mRemainingScreenColor = 0;
|
||||
mShelfColor = 0;
|
||||
ShelfPeekAnim shelfPeekAnim = ((QuickstepAppTransitionManagerImpl)
|
||||
mLauncher.getAppTransitionManager()).getShelfPeekAnim();
|
||||
LauncherState state = mLauncher.getStateManager().getState();
|
||||
if (mSysUINavigationMode == Mode.NO_BUTTON
|
||||
&& mLauncher.getStateManager().getState() == BACKGROUND_APP) {
|
||||
&& (state == BACKGROUND_APP || state == QUICK_SWITCH)
|
||||
&& shelfPeekAnim.isPeeking()) {
|
||||
// Show the shelf background when peeking during swipe up.
|
||||
mShelfColor = setColorAlphaBound(mEndScrim, mMidAlpha);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,8 @@ import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
|
||||
import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
@@ -32,7 +33,6 @@ import com.android.launcher3.anim.AnimatorSetBuilder;
|
||||
import com.android.launcher3.anim.PropertySetter;
|
||||
import com.android.launcher3.anim.PropertySetter.AnimatedPropertySetter;
|
||||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.uioverrides.UiFactory;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -40,8 +40,6 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import androidx.annotation.IntDef;
|
||||
|
||||
/**
|
||||
* TODO: figure out what kind of tests we can write for this
|
||||
*
|
||||
|
||||
@@ -27,7 +27,7 @@ import android.view.ViewGroup;
|
||||
*/
|
||||
public class AlphaUpdateListener extends AnimationSuccessListener
|
||||
implements AnimatorUpdateListener {
|
||||
private static final float ALPHA_CUTOFF_THRESHOLD = 0.01f;
|
||||
public static final float ALPHA_CUTOFF_THRESHOLD = 0.01f;
|
||||
|
||||
private View mView;
|
||||
|
||||
|
||||
@@ -26,15 +26,15 @@ import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.dynamicanimation.animation.DynamicAnimation;
|
||||
import androidx.dynamicanimation.animation.SpringAnimation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import androidx.dynamicanimation.animation.DynamicAnimation;
|
||||
import androidx.dynamicanimation.animation.SpringAnimation;
|
||||
|
||||
/**
|
||||
* Helper class to control the playback of an {@link AnimatorSet}, with custom interpolators
|
||||
* and durations.
|
||||
@@ -250,6 +250,17 @@ public abstract class AnimatorPlaybackController implements ValueAnimator.Animat
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets mOnCancelRunnable = null before dispatching the cancel and restoring the runnable. This
|
||||
* is intended to be used only if you need to cancel but want to defer cleaning up yourself.
|
||||
*/
|
||||
public void dispatchOnCancelWithoutCancelRunnable() {
|
||||
Runnable onCancel = mOnCancelRunnable;
|
||||
setOnCancelRunnable(null);
|
||||
dispatchOnCancel();
|
||||
setOnCancelRunnable(onCancel);
|
||||
}
|
||||
|
||||
public void dispatchOnCancel() {
|
||||
dispatchOnCancelRecursively(mAnim);
|
||||
}
|
||||
@@ -283,10 +294,6 @@ public abstract class AnimatorPlaybackController implements ValueAnimator.Animat
|
||||
mOnCancelRunnable = runnable;
|
||||
}
|
||||
|
||||
public Runnable getOnCancelRunnable() {
|
||||
return mOnCancelRunnable;
|
||||
}
|
||||
|
||||
public void skipToEnd() {
|
||||
mSkipToEnd = true;
|
||||
for (SpringAnimation spring : mSprings) {
|
||||
|
||||
@@ -39,6 +39,7 @@ public class Interpolators {
|
||||
public static final Interpolator LINEAR = new LinearInterpolator();
|
||||
|
||||
public static final Interpolator ACCEL = new AccelerateInterpolator();
|
||||
public static final Interpolator ACCEL_0_75 = new AccelerateInterpolator(0.75f);
|
||||
public static final Interpolator ACCEL_1_5 = new AccelerateInterpolator(1.5f);
|
||||
public static final Interpolator ACCEL_2 = new AccelerateInterpolator(2);
|
||||
|
||||
@@ -48,6 +49,7 @@ public class Interpolators {
|
||||
public static final Interpolator DEACCEL_2 = new DecelerateInterpolator(2);
|
||||
public static final Interpolator DEACCEL_2_5 = new DecelerateInterpolator(2.5f);
|
||||
public static final Interpolator DEACCEL_3 = new DecelerateInterpolator(3f);
|
||||
public static final Interpolator DEACCEL_5 = new DecelerateInterpolator(5f);
|
||||
|
||||
public static final Interpolator ACCEL_DEACCEL = new AccelerateDecelerateInterpolator();
|
||||
|
||||
|
||||
@@ -413,10 +413,7 @@ public abstract class AbstractStateChangeTouchController
|
||||
} else {
|
||||
// Let the state manager know that the animation didn't go to the target state,
|
||||
// but don't cancel ourselves (we already clean up when the animation completes).
|
||||
Runnable onCancel = mCurrentAnimation.getOnCancelRunnable();
|
||||
mCurrentAnimation.setOnCancelRunnable(null);
|
||||
mCurrentAnimation.dispatchOnCancel();
|
||||
mCurrentAnimation.setOnCancelRunnable(onCancel);
|
||||
mCurrentAnimation.dispatchOnCancelWithoutCancelRunnable();
|
||||
|
||||
endProgress = 0;
|
||||
if (progress <= 0) {
|
||||
|
||||
Reference in New Issue
Block a user