Merge "Add long swipe from app to overview gesture (with flag)." into udc-dev am: a4627d2235
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/22243545 Change-Id: Ic4aa2767cf1e12ed901d6dabdc3e67503a5b1d43 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -63,5 +63,6 @@ message GestureStateProto {
|
||||
RECENTS = 2;
|
||||
NEW_TASK = 3;
|
||||
LAST_TASK = 4;
|
||||
ALL_APPS = 5;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
|
||||
import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK;
|
||||
import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
|
||||
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.ALL_APPS;
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.HOME;
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.NEW_TASK;
|
||||
@@ -161,6 +162,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
private static final ArrayList<String> STATE_NAMES = new ArrayList<>();
|
||||
|
||||
/** Shift distance to transition to All Apps if ENABLE_ALL_APPS_FROM_OVERVIEW. */
|
||||
public static final float ALL_APPS_SHIFT_THRESHOLD = 2f;
|
||||
|
||||
protected final BaseActivityInterface<S, T> mActivityInterface;
|
||||
protected final InputConsumerProxy mInputConsumerProxy;
|
||||
protected final ActivityInitListener mActivityInitListener;
|
||||
@@ -247,6 +251,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
getNextStateFlag("STATE_CURRENT_TASK_FINISHED");
|
||||
private static final int STATE_FINISH_WITH_NO_END =
|
||||
getNextStateFlag("STATE_FINISH_WITH_NO_END");
|
||||
private static final int STATE_SETTLED_ON_ALL_APPS =
|
||||
getNextStateFlag("STATE_SETTLED_ON_ALL_APPS");
|
||||
|
||||
private static final int LAUNCHER_UI_STATES =
|
||||
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_LAUNCHER_STARTED |
|
||||
@@ -299,6 +305,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
private boolean mGestureStarted;
|
||||
private boolean mLogDirectionUpOrLeft = true;
|
||||
private boolean mIsLikelyToStartNewTask;
|
||||
private boolean mIsInAllAppsRegion;
|
||||
|
||||
private final long mTouchTimeMs;
|
||||
private long mLauncherFrameDrawnTime;
|
||||
@@ -432,6 +439,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
this::finishCurrentTransitionToHome);
|
||||
mStateCallback.runOnceAtState(STATE_SCALED_CONTROLLER_HOME | STATE_CURRENT_TASK_FINISHED,
|
||||
this::reset);
|
||||
mStateCallback.runOnceAtState(STATE_SETTLED_ON_ALL_APPS | STATE_SCREENSHOT_CAPTURED
|
||||
| STATE_GESTURE_COMPLETED,
|
||||
this::finishCurrentTransitionToAllApps);
|
||||
|
||||
mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
|
||||
| STATE_LAUNCHER_DRAWN | STATE_SCALED_CONTROLLER_RECENTS
|
||||
@@ -681,7 +691,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
maybeUpdateRecentsAttachedState(true/* animate */, true/* moveRunningTask */);
|
||||
Optional.ofNullable(mActivityInterface.getTaskbarController())
|
||||
.ifPresent(TaskbarUIController::startTranslationSpring);
|
||||
performHapticFeedback();
|
||||
if (!mIsInAllAppsRegion) {
|
||||
performHapticFeedback();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -695,7 +707,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
maybeUpdateRecentsAttachedState(true /* animate */);
|
||||
}
|
||||
|
||||
private void maybeUpdateRecentsAttachedState(boolean animate) {
|
||||
protected void maybeUpdateRecentsAttachedState(boolean animate) {
|
||||
maybeUpdateRecentsAttachedState(animate, false /* moveRunningTask */);
|
||||
}
|
||||
|
||||
@@ -716,7 +728,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
? mRecentsAnimationTargets.findTask(mGestureState.getRunningTaskId())
|
||||
: null;
|
||||
final boolean recentsAttachedToAppWindow;
|
||||
if (mGestureState.getEndTarget() != null) {
|
||||
if (mIsInAllAppsRegion) {
|
||||
recentsAttachedToAppWindow = false;
|
||||
} else if (mGestureState.getEndTarget() != null) {
|
||||
recentsAttachedToAppWindow = mGestureState.getEndTarget().recentsAttachedToAppWindow;
|
||||
} else if (mContinuingLastGesture
|
||||
&& mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) {
|
||||
@@ -772,6 +786,26 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update whether user is currently dragging in a region that will trigger all apps.
|
||||
*/
|
||||
private void setIsInAllAppsRegion(boolean isInAllAppsRegion) {
|
||||
if (mIsInAllAppsRegion == isInAllAppsRegion
|
||||
|| !mActivityInterface.allowAllAppsFromOverview()) {
|
||||
return;
|
||||
}
|
||||
mIsInAllAppsRegion = isInAllAppsRegion;
|
||||
|
||||
// Newly entering or exiting the zone - do haptic and animate recent tasks.
|
||||
VibratorWrapper.INSTANCE.get(mContext).vibrate(OVERVIEW_HAPTIC);
|
||||
maybeUpdateRecentsAttachedState(true);
|
||||
|
||||
// Draw active task below Launcher so that All Apps can appear over it.
|
||||
runActionOnRemoteHandles(remoteTargetHandle ->
|
||||
remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(isInAllAppsRegion));
|
||||
}
|
||||
|
||||
|
||||
private void buildAnimationController() {
|
||||
if (!canCreateNewOrUpdateExistingLauncherTransitionController()) {
|
||||
return;
|
||||
@@ -792,10 +826,15 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
@Override
|
||||
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
|
||||
WindowInsets result = view.onApplyWindowInsets(windowInsets);
|
||||
// Don't rebuild animation when we are animating the IME, because it will cause a loop
|
||||
// where the insets change -> animation changes (updating ime) -> insets change -> ...
|
||||
if (windowInsets.isVisible(WindowInsets.Type.ime())) {
|
||||
return result;
|
||||
}
|
||||
buildAnimationController();
|
||||
// Reapply the current shift to ensure it takes new insets into account, e.g. when long
|
||||
// pressing to stash taskbar without moving the finger.
|
||||
updateFinalShift();
|
||||
onCurrentShiftUpdated();
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -822,7 +861,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
*/
|
||||
@UiThread
|
||||
@Override
|
||||
public void updateFinalShift() {
|
||||
public void onCurrentShiftUpdated() {
|
||||
setIsInAllAppsRegion(mCurrentShift.value >= ALL_APPS_SHIFT_THRESHOLD);
|
||||
updateSysUiFlags(mCurrentShift.value);
|
||||
applyScrollAndTransform();
|
||||
|
||||
@@ -1085,6 +1125,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
}
|
||||
|
||||
switch (endTarget) {
|
||||
case ALL_APPS:
|
||||
mStateCallback.setState(STATE_SETTLED_ON_ALL_APPS | STATE_CAPTURE_SCREENSHOT);
|
||||
break;
|
||||
case HOME:
|
||||
mStateCallback.setState(STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT);
|
||||
// Notify the SysUI to use fade-in animation when entering PiP
|
||||
@@ -1173,6 +1216,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
final boolean willGoToNewTask =
|
||||
isScrollingToNewTask() && Math.abs(velocity.x) > Math.abs(endVelocity);
|
||||
final boolean isSwipeUp = endVelocity < 0;
|
||||
if (mIsInAllAppsRegion) {
|
||||
return isSwipeUp ? ALL_APPS : LAST_TASK;
|
||||
}
|
||||
if (!isSwipeUp) {
|
||||
final boolean isCenteredOnNewTask =
|
||||
mRecentsView.getDestinationPage() != mRecentsView.getRunningTaskIndex();
|
||||
@@ -1188,7 +1234,9 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
// Fully gestural mode.
|
||||
final boolean isFlingX = Math.abs(velocity.x) > mContext.getResources()
|
||||
.getDimension(R.dimen.quickstep_fling_threshold_speed);
|
||||
if (isScrollingToNewTask && isFlingX) {
|
||||
if (mIsInAllAppsRegion) {
|
||||
return ALL_APPS;
|
||||
} else if (isScrollingToNewTask && isFlingX) {
|
||||
// Flinging towards new task takes precedence over mIsMotionPaused (which only
|
||||
// checks y-velocity).
|
||||
return NEW_TASK;
|
||||
@@ -1236,7 +1284,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
mGestureState.setEndTarget(endTarget, false /* isAtomic */);
|
||||
mAnimationFactory.setEndTarget(endTarget);
|
||||
|
||||
float endShift = endTarget.isLauncher ? 1 : 0;
|
||||
float endShift = endTarget == ALL_APPS ? mDragLengthFactor
|
||||
: endTarget.isLauncher ? 1 : 0;
|
||||
final float startShift;
|
||||
if (!isFling) {
|
||||
long expectedDuration = Math.abs(Math.round((endShift - currentShift)
|
||||
@@ -1793,6 +1842,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
reset();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void finishCurrentTransitionToAllApps() {
|
||||
finishCurrentTransitionToHome();
|
||||
reset();
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
mStateCallback.setStateOnUiThread(STATE_HANDLER_INVALIDATED);
|
||||
if (mActivity != null) {
|
||||
@@ -1926,7 +1981,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
private boolean updateThumbnail(int runningTaskId, boolean refreshView) {
|
||||
boolean finishTransitionPosted = false;
|
||||
final TaskView taskView;
|
||||
if (mGestureState.getEndTarget() == HOME || mGestureState.getEndTarget() == NEW_TASK) {
|
||||
if (mGestureState.getEndTarget() == HOME || mGestureState.getEndTarget() == NEW_TASK
|
||||
|| mGestureState.getEndTarget() == ALL_APPS) {
|
||||
// Capture the screenshot before finishing the transition to home or quickswitching to
|
||||
// ensure it's taken in the correct orientation, but no need to update the thumbnail.
|
||||
taskView = null;
|
||||
@@ -2072,7 +2128,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
private void onRecentsViewScroll() {
|
||||
if (moveWindowWithRecentsScroll()) {
|
||||
updateFinalShift();
|
||||
onCurrentShiftUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -187,6 +187,9 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||
|
||||
public abstract boolean allowMinimizeSplitScreen();
|
||||
|
||||
/** @return whether to allow going to All Apps from Overview. */
|
||||
public abstract boolean allowAllAppsFromOverview();
|
||||
|
||||
public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
|
||||
return deviceState.isInDeferredGestureRegion(ev) || deviceState.isImeRenderingNavButtons()
|
||||
|| isTrackpadMultiFingerSwipe(ev);
|
||||
|
||||
@@ -138,6 +138,11 @@ public final class FallbackActivityInterface extends
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowAllAppsFromOverview() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
|
||||
// In non-gesture mode, user might be clicking on the home button which would directly
|
||||
@@ -196,6 +201,7 @@ public final class FallbackActivityInterface extends
|
||||
case LAST_TASK:
|
||||
return BACKGROUND_APP;
|
||||
case HOME:
|
||||
case ALL_APPS:
|
||||
default:
|
||||
return HOME;
|
||||
}
|
||||
|
||||
@@ -18,11 +18,13 @@ package com.android.quickstep;
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadFourFingerSwipe;
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
|
||||
import static com.android.launcher3.MotionEventsUtils.isTrackpadThreeFingerSwipe;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
|
||||
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
|
||||
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET;
|
||||
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_ALL_APPS;
|
||||
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_HOME;
|
||||
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.SET_END_TARGET_NEW_TASK;
|
||||
|
||||
@@ -68,7 +70,9 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
||||
GestureStateProto.GestureEndTarget.NEW_TASK),
|
||||
|
||||
LAST_TASK(false, LAUNCHER_STATE_BACKGROUND, true,
|
||||
GestureStateProto.GestureEndTarget.LAST_TASK);
|
||||
GestureStateProto.GestureEndTarget.LAST_TASK),
|
||||
|
||||
ALL_APPS(true, LAUNCHER_STATE_ALLAPPS, false, GestureStateProto.GestureEndTarget.ALL_APPS);
|
||||
|
||||
GestureEndTarget(boolean isLauncher, int containerType, boolean recentsAttachedToAppWindow,
|
||||
GestureStateProto.GestureEndTarget protoEndTarget) {
|
||||
@@ -385,6 +389,9 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
|
||||
case NEW_TASK:
|
||||
ActiveGestureLog.INSTANCE.trackEvent(SET_END_TARGET_NEW_TASK);
|
||||
break;
|
||||
case ALL_APPS:
|
||||
ActiveGestureLog.INSTANCE.trackEvent(SET_END_TARGET_ALL_APPS);
|
||||
break;
|
||||
case LAST_TASK:
|
||||
case RECENTS:
|
||||
default:
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.BACKGROUND_APP;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
@@ -39,6 +40,7 @@ import com.android.launcher3.LauncherAnimUtils;
|
||||
import com.android.launcher3.LauncherInitListener;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.statehandlers.DesktopVisibilityController;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
@@ -263,6 +265,11 @@ public final class LauncherActivityInterface extends
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowAllAppsFromOverview() {
|
||||
return FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInLiveTileMode() {
|
||||
Launcher launcher = getCreatedActivity();
|
||||
@@ -347,6 +354,8 @@ public final class LauncherActivityInterface extends
|
||||
case NEW_TASK:
|
||||
case LAST_TASK:
|
||||
return BACKGROUND_APP;
|
||||
case ALL_APPS:
|
||||
return ALL_APPS;
|
||||
case HOME:
|
||||
default:
|
||||
return NORMAL;
|
||||
|
||||
@@ -350,7 +350,8 @@ public class RotationTouchHelper implements DisplayInfoChangeListener {
|
||||
enableMultipleRegions(true);
|
||||
}
|
||||
activityInterface.onExitOverview(this, mExitOverviewRunnable);
|
||||
} else if (endTarget == GestureState.GestureEndTarget.HOME) {
|
||||
} else if (endTarget == GestureState.GestureEndTarget.HOME
|
||||
|| endTarget == GestureState.GestureEndTarget.ALL_APPS) {
|
||||
enableMultipleRegions(false);
|
||||
} else if (endTarget == GestureState.GestureEndTarget.NEW_TASK) {
|
||||
if (mOrientationTouchTransformer.getQuickStepStartingRotation() == -1) {
|
||||
|
||||
@@ -67,7 +67,7 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
// 0 => preview snapShot is completely visible, and hotseat is completely translated down
|
||||
// 1 => preview snapShot is completely aligned with the recents view and hotseat is completely
|
||||
// visible.
|
||||
protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift);
|
||||
protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::onCurrentShiftUpdated);
|
||||
protected float mCurrentDisplacement;
|
||||
|
||||
// The distance needed to drag to reach the task size in recents.
|
||||
@@ -148,7 +148,7 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
* Called when the value of {@link #mCurrentShift} changes
|
||||
*/
|
||||
@UiThread
|
||||
public abstract void updateFinalShift();
|
||||
public abstract void onCurrentShiftUpdated();
|
||||
|
||||
protected PagedOrientationHandler getOrientationHandler() {
|
||||
// OrientationHandler should be independent of remote target, can directly take one
|
||||
|
||||
+1
-1
@@ -309,7 +309,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFinalShift() {
|
||||
public void onCurrentShiftUpdated() {
|
||||
mRemoteTargetHandles[0].getPlaybackController()
|
||||
.setProgress(mCurrentShift.value, mDragLengthFactor);
|
||||
mRemoteTargetHandles[0].getTaskViewSimulator().apply(
|
||||
|
||||
@@ -33,10 +33,11 @@ public class ActiveGestureErrorDetector {
|
||||
*/
|
||||
public enum GestureEvent {
|
||||
MOTION_DOWN, MOTION_UP, MOTION_MOVE, SET_END_TARGET, SET_END_TARGET_HOME,
|
||||
SET_END_TARGET_NEW_TASK, ON_SETTLED_ON_END_TARGET, START_RECENTS_ANIMATION,
|
||||
FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION, SET_ON_PAGE_TRANSITION_END_CALLBACK,
|
||||
CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT, SCROLLER_ANIMATION_ABORTED, TASK_APPEARED,
|
||||
EXPECTING_TASK_APPEARED, FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, LAUNCHER_DESTROYED,
|
||||
SET_END_TARGET_NEW_TASK, SET_END_TARGET_ALL_APPS, ON_SETTLED_ON_END_TARGET,
|
||||
START_RECENTS_ANIMATION, FINISH_RECENTS_ANIMATION, CANCEL_RECENTS_ANIMATION,
|
||||
SET_ON_PAGE_TRANSITION_END_CALLBACK, CANCEL_CURRENT_ANIMATION, CLEANUP_SCREENSHOT,
|
||||
SCROLLER_ANIMATION_ABORTED, TASK_APPEARED, EXPECTING_TASK_APPEARED,
|
||||
FLAG_USING_OTHER_ACTIVITY_INPUT_CONSUMER, LAUNCHER_DESTROYED,
|
||||
|
||||
/**
|
||||
* These GestureEvents are specifically associated to state flags that get set in
|
||||
@@ -220,6 +221,7 @@ public class ActiveGestureErrorDetector {
|
||||
case MOTION_DOWN:
|
||||
case SET_END_TARGET:
|
||||
case SET_END_TARGET_HOME:
|
||||
case SET_END_TARGET_ALL_APPS:
|
||||
case SET_END_TARGET_NEW_TASK:
|
||||
case START_RECENTS_ANIMATION:
|
||||
case SET_ON_PAGE_TRANSITION_END_CALLBACK:
|
||||
|
||||
@@ -17,9 +17,11 @@ package com.android.quickstep.util;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.quickstep.AbsSwipeUpHandler.ALL_APPS_SHIFT_THRESHOLD;
|
||||
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
|
||||
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.content.Context;
|
||||
import android.graphics.Matrix;
|
||||
@@ -32,11 +34,15 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.touch.AllAppsSwipeController;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.quickstep.LauncherActivityInterface;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
|
||||
/**
|
||||
@@ -49,7 +55,9 @@ public class AnimatorControllerWithResistance {
|
||||
|
||||
private enum RecentsResistanceParams {
|
||||
FROM_APP(0.75f, 0.5f, 1f, false),
|
||||
FROM_APP_TO_ALL_APPS(0.75f, 0.5f, 0.8f, false),
|
||||
FROM_APP_TABLET(1f, 0.7f, 1f, true),
|
||||
FROM_APP_TO_ALL_APPS_TABLET(1f, 0.5f, 0.5f, false),
|
||||
FROM_OVERVIEW(1f, 0.75f, 0.5f, false);
|
||||
|
||||
RecentsResistanceParams(float scaleStartResist, float scaleMaxResist,
|
||||
@@ -86,6 +94,8 @@ public class AnimatorControllerWithResistance {
|
||||
private static final TimeInterpolator RECENTS_SCALE_RESIST_INTERPOLATOR = DEACCEL;
|
||||
private static final TimeInterpolator RECENTS_TRANSLATE_RESIST_INTERPOLATOR = LINEAR;
|
||||
|
||||
private static final Rect TEMP_RECT = new Rect();
|
||||
|
||||
private final AnimatorPlaybackController mNormalController;
|
||||
private final AnimatorPlaybackController mResistanceController;
|
||||
|
||||
@@ -145,10 +155,42 @@ public class AnimatorControllerWithResistance {
|
||||
scaleProperty, translationTarget, translationProperty);
|
||||
PendingAnimation resistAnim = createRecentsResistanceAnim(params);
|
||||
|
||||
// Apply All Apps animation during the resistance animation.
|
||||
if (recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()) {
|
||||
StatefulActivity activity =
|
||||
recentsOrientedState.getActivityInterface().getCreatedActivity();
|
||||
if (activity != null) {
|
||||
StateManager<LauncherState> stateManager = activity.getStateManager();
|
||||
if (stateManager.isInStableState(LauncherState.BACKGROUND_APP)
|
||||
&& stateManager.isInTransition()) {
|
||||
|
||||
// Calculate the resistance progress threshold where All Apps will trigger.
|
||||
float threshold = getAllAppsThreshold(context, recentsOrientedState, dp);
|
||||
|
||||
StateAnimationConfig config = new StateAnimationConfig();
|
||||
AllAppsSwipeController.applyOverviewToAllAppsAnimConfig(dp, config, threshold);
|
||||
AnimatorSet allAppsAnimator = stateManager.createAnimationToNewWorkspace(
|
||||
LauncherState.ALL_APPS, config).getTarget();
|
||||
resistAnim.add(allAppsAnimator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AnimatorPlaybackController resistanceController = resistAnim.createPlaybackController();
|
||||
return new AnimatorControllerWithResistance(normalController, resistanceController);
|
||||
}
|
||||
|
||||
private static float getAllAppsThreshold(Context context,
|
||||
RecentsOrientedState recentsOrientedState, DeviceProfile dp) {
|
||||
int transitionDragLength =
|
||||
recentsOrientedState.getActivityInterface().getSwipeUpDestinationAndLength(
|
||||
dp, context, TEMP_RECT,
|
||||
recentsOrientedState.getOrientationHandler());
|
||||
float dragLengthFactor = (float) dp.heightPx / transitionDragLength;
|
||||
// -1s are because 0-1 is reserved for the normal transition.
|
||||
return (ALL_APPS_SHIFT_THRESHOLD - 1) / (dragLengthFactor - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the resistance animation for {@link #createForRecents}, or can be used separately
|
||||
* when starting from recents, i.e. {@link #createRecentsResistanceFromOverviewAnim}.
|
||||
@@ -158,8 +200,8 @@ public class AnimatorControllerWithResistance {
|
||||
Rect startRect = new Rect();
|
||||
PagedOrientationHandler orientationHandler = params.recentsOrientedState
|
||||
.getOrientationHandler();
|
||||
LauncherActivityInterface.INSTANCE.calculateTaskSize(params.context, params.dp, startRect,
|
||||
orientationHandler);
|
||||
params.recentsOrientedState.getActivityInterface()
|
||||
.calculateTaskSize(params.context, params.dp, startRect, orientationHandler);
|
||||
long distanceToCover = startRect.bottom;
|
||||
PendingAnimation resistAnim = params.resistAnim != null
|
||||
? params.resistAnim
|
||||
@@ -257,9 +299,15 @@ public class AnimatorControllerWithResistance {
|
||||
this.translationTarget = translationTarget;
|
||||
this.translationProperty = translationProperty;
|
||||
if (dp.isTablet) {
|
||||
resistanceParams = RecentsResistanceParams.FROM_APP_TABLET;
|
||||
resistanceParams =
|
||||
recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()
|
||||
? RecentsResistanceParams.FROM_APP_TO_ALL_APPS_TABLET
|
||||
: RecentsResistanceParams.FROM_APP_TABLET;
|
||||
} else {
|
||||
resistanceParams = RecentsResistanceParams.FROM_APP;
|
||||
resistanceParams =
|
||||
recentsOrientedState.getActivityInterface().allowAllAppsFromOverview()
|
||||
? RecentsResistanceParams.FROM_APP_TO_ALL_APPS
|
||||
: RecentsResistanceParams.FROM_APP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -116,6 +116,7 @@ public class RecentsOrientedState implements
|
||||
| FLAG_SWIPE_UP_NOT_RUNNING;
|
||||
|
||||
private final Context mContext;
|
||||
private final BaseActivityInterface mActivityInterface;
|
||||
private final OrientationEventListener mOrientationListener;
|
||||
private final SettingsCache mSettingsCache;
|
||||
private final SettingsCache.OnChangeListener mRotationChangeListener =
|
||||
@@ -135,9 +136,10 @@ public class RecentsOrientedState implements
|
||||
* is enabled
|
||||
* @see #setRotationWatcherEnabled(boolean)
|
||||
*/
|
||||
public RecentsOrientedState(Context context, BaseActivityInterface sizeStrategy,
|
||||
public RecentsOrientedState(Context context, BaseActivityInterface activityInterface,
|
||||
IntConsumer rotationChangeListener) {
|
||||
mContext = context;
|
||||
mActivityInterface = activityInterface;
|
||||
mOrientationListener = new OrientationEventListener(context) {
|
||||
@Override
|
||||
public void onOrientationChanged(int degrees) {
|
||||
@@ -149,7 +151,7 @@ public class RecentsOrientedState implements
|
||||
}
|
||||
};
|
||||
|
||||
mFlags = sizeStrategy.rotationSupportedByActivity
|
||||
mFlags = mActivityInterface.rotationSupportedByActivity
|
||||
? FLAG_MULTIPLE_ORIENTATION_SUPPORTED_BY_ACTIVITY : 0;
|
||||
|
||||
mFlags |= FLAG_SWIPE_UP_NOT_RUNNING;
|
||||
@@ -157,6 +159,10 @@ public class RecentsOrientedState implements
|
||||
initFlags();
|
||||
}
|
||||
|
||||
public BaseActivityInterface getActivityInterface() {
|
||||
return mActivityInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the device profile for the current state.
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.android.quickstep.views;
|
||||
|
||||
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
|
||||
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.CLEAR_ALL_BUTTON;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
@@ -129,7 +130,7 @@ public class LauncherRecentsView extends RecentsView<QuickstepLauncher, Launcher
|
||||
|
||||
@Override
|
||||
public void onStateTransitionComplete(LauncherState finalState) {
|
||||
if (finalState == NORMAL || finalState == SPRING_LOADED) {
|
||||
if (finalState == NORMAL || finalState == SPRING_LOADED || finalState == ALL_APPS) {
|
||||
// Clean-up logic that occurs when recents is no longer in use/visible.
|
||||
reset();
|
||||
}
|
||||
|
||||
@@ -68,16 +68,16 @@
|
||||
android:id="@+id/scrim_view"
|
||||
android:background="@android:color/transparent" />
|
||||
|
||||
<include
|
||||
android:id="@+id/overview_panel"
|
||||
layout="@layout/overview_panel" />
|
||||
|
||||
<include
|
||||
android:id="@+id/apps_view"
|
||||
layout="@layout/all_apps"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<include
|
||||
android:id="@+id/overview_panel"
|
||||
layout="@layout/overview_panel" />
|
||||
|
||||
</com.android.launcher3.dragndrop.DragLayer>
|
||||
|
||||
</com.android.launcher3.LauncherRootView>
|
||||
|
||||
@@ -40,6 +40,7 @@ import android.os.Parcelable;
|
||||
import android.os.Process;
|
||||
import android.os.UserManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.FloatProperty;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.util.TypedValue;
|
||||
@@ -101,6 +102,20 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
|
||||
OnDeviceProfileChangeListener, PersonalWorkSlidingTabStrip.OnActivePageChangedListener,
|
||||
ScrimView.ScrimDrawingController {
|
||||
|
||||
|
||||
public static final FloatProperty<ActivityAllAppsContainerView<?>> BOTTOM_SHEET_ALPHA =
|
||||
new FloatProperty<>("bottomSheetAlpha") {
|
||||
@Override
|
||||
public Float get(ActivityAllAppsContainerView<?> containerView) {
|
||||
return containerView.mBottomSheetAlpha;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(ActivityAllAppsContainerView<?> containerView, float v) {
|
||||
containerView.setBottomSheetAlpha(v);
|
||||
}
|
||||
};
|
||||
|
||||
public static final float PULL_MULTIPLIER = .02f;
|
||||
public static final float FLING_VELOCITY_MULTIPLIER = 1200f;
|
||||
protected static final String BUNDLE_KEY_CURRENT_PAGE = "launcher.allapps.current_page";
|
||||
@@ -159,6 +174,8 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
|
||||
private ScrimView mScrimView;
|
||||
private int mHeaderColor;
|
||||
private int mBottomSheetBackgroundColor;
|
||||
private float mBottomSheetAlpha = 1f;
|
||||
private boolean mForceBottomSheetVisible;
|
||||
private int mTabsProtectionAlpha;
|
||||
@Nullable private AllAppsTransitionController mAllAppsTransitionController;
|
||||
|
||||
@@ -258,7 +275,7 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
|
||||
final TypedValue value = new TypedValue();
|
||||
getContext().getTheme().resolveAttribute(android.R.attr.colorBackground, value, true);
|
||||
mBottomSheetBackgroundColor = value.data;
|
||||
updateBackground(mActivityContext.getDeviceProfile());
|
||||
updateBackgroundVisibility(mActivityContext.getDeviceProfile());
|
||||
mSearchUiManager.initializeSearch(this);
|
||||
}
|
||||
|
||||
@@ -282,6 +299,16 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
|
||||
return mBottomSheetBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporarily force the bottom sheet to be visible on non-tablets.
|
||||
*
|
||||
* @param force {@code true} means bottom sheet will be visible on phones until {@code reset()}.
|
||||
**/
|
||||
public void forceBottomSheetVisible(boolean force) {
|
||||
mForceBottomSheetVisible = force;
|
||||
updateBackgroundVisibility(mActivityContext.getDeviceProfile());
|
||||
}
|
||||
|
||||
public View getSearchView() {
|
||||
return mSearchContainer;
|
||||
}
|
||||
@@ -408,6 +435,7 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
|
||||
if (mHeader != null && mHeader.getVisibility() == VISIBLE) {
|
||||
mHeader.reset(animate);
|
||||
}
|
||||
forceBottomSheetVisible(false);
|
||||
// Reset the base recycler view after transitioning home.
|
||||
updateHeaderScroll(0);
|
||||
if (exitSearch) {
|
||||
@@ -830,7 +858,7 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
|
||||
holder.mRecyclerView.getRecycledViewPool().clear();
|
||||
}
|
||||
}
|
||||
updateBackground(dp);
|
||||
updateBackgroundVisibility(dp);
|
||||
|
||||
int navBarScrimColor = Themes.getNavBarScrimColor(mActivityContext);
|
||||
if (mNavBarScrimPaint.getColor() != navBarScrimColor) {
|
||||
@@ -839,13 +867,19 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateBackground(DeviceProfile deviceProfile) {
|
||||
mBottomSheetBackground.setVisibility(deviceProfile.isTablet ? View.VISIBLE : View.GONE);
|
||||
protected void updateBackgroundVisibility(DeviceProfile deviceProfile) {
|
||||
boolean visible = deviceProfile.isTablet || mForceBottomSheetVisible;
|
||||
mBottomSheetBackground.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
// Note: For tablets, the opaque background and header protection are added in drawOnScrim.
|
||||
// For the taskbar entrypoint, the scrim is drawn differently, so a static background is
|
||||
// added in TaskbarAllAppsContainerView and header protection is not yet supported.
|
||||
}
|
||||
|
||||
private void setBottomSheetAlpha(float alpha) {
|
||||
// Bottom sheet alpha is always 1 for tablets.
|
||||
mBottomSheetAlpha = mActivityContext.getDeviceProfile().isTablet ? 1f : alpha;
|
||||
}
|
||||
|
||||
private void onAppsUpdated() {
|
||||
mHasWorkApps = Stream.of(mAllAppsStore.getApps()).anyMatch(mWorkManager.getMatcher());
|
||||
if (TestProtocol.sDebugTracing) {
|
||||
@@ -1148,8 +1182,8 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
|
||||
|
||||
@Override
|
||||
public void drawOnScrimWithScale(Canvas canvas, float scale) {
|
||||
final boolean isTablet = mActivityContext.getDeviceProfile().isTablet;
|
||||
final View panel = mBottomSheetBackground;
|
||||
final boolean hasBottomSheet = panel.getVisibility() == VISIBLE;
|
||||
final float translationY = ((View) panel.getParent()).getTranslationY();
|
||||
|
||||
final float horizontalScaleOffset = (1 - scale) * panel.getWidth() / 2;
|
||||
@@ -1160,8 +1194,9 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
|
||||
final float leftWithScale = panel.getLeft() + horizontalScaleOffset;
|
||||
final float rightWithScale = panel.getRight() - horizontalScaleOffset;
|
||||
// Draw full background panel for tablets.
|
||||
if (isTablet) {
|
||||
if (hasBottomSheet) {
|
||||
mHeaderPaint.setColor(mBottomSheetBackgroundColor);
|
||||
mHeaderPaint.setAlpha((int) (255 * mBottomSheetAlpha));
|
||||
|
||||
mTmpRectF.set(
|
||||
leftWithScale,
|
||||
@@ -1192,7 +1227,7 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
|
||||
final float headerBottomOffset = (getVisibleContainerView().getHeight() * (1 - scale) / 2);
|
||||
final float headerBottomWithScaleOnPhone = headerBottomNoScale * scale + headerBottomOffset;
|
||||
final FloatingHeaderView headerView = getFloatingHeaderView();
|
||||
if (isTablet) {
|
||||
if (hasBottomSheet) {
|
||||
// Start adding header protection if search bar or tabs will attach to the top.
|
||||
if (!FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get() || mUsingTabs) {
|
||||
mTmpRectF.set(
|
||||
@@ -1219,12 +1254,12 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
|
||||
}
|
||||
float left = 0f;
|
||||
float right = canvas.getWidth();
|
||||
if (isTablet) {
|
||||
if (hasBottomSheet) {
|
||||
left = mBottomSheetBackground.getLeft() + horizontalScaleOffset;
|
||||
right = mBottomSheetBackground.getRight() - horizontalScaleOffset;
|
||||
}
|
||||
|
||||
final float tabTopWithScale = isTablet
|
||||
final float tabTopWithScale = hasBottomSheet
|
||||
? headerBottomWithScaleOnTablet
|
||||
: headerBottomWithScaleOnPhone;
|
||||
final float tabBottomWithScale = tabTopWithScale + tabsHeight * scale;
|
||||
@@ -1263,7 +1298,7 @@ public class ActivityAllAppsContainerView<T extends Context & ActivityContext>
|
||||
* Returns a view that denotes the visible part of all apps container view.
|
||||
*/
|
||||
public View getVisibleContainerView() {
|
||||
return mActivityContext.getDeviceProfile().isTablet ? mBottomSheetBackground : this;
|
||||
return mBottomSheetBackground.getVisibility() == VISIBLE ? mBottomSheetBackground : this;
|
||||
}
|
||||
|
||||
protected void onInitializeRecyclerView(RecyclerView rv) {
|
||||
|
||||
@@ -21,8 +21,10 @@ import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7;
|
||||
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||
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_BOTTOM_SHEET_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
|
||||
import static com.android.launcher3.util.SystemUiController.FLAG_DARK_NAV;
|
||||
@@ -410,8 +412,12 @@ public class AllAppsTransitionController
|
||||
setter.setFloat(getAppsViewPullbackAlpha(), MultiPropertyFactory.MULTI_PROPERTY_VALUE,
|
||||
hasAllAppsContent ? 1 : 0, allAppsFade);
|
||||
|
||||
boolean shouldProtectHeader =
|
||||
ALL_APPS == state || mLauncher.getStateManager().getState() == ALL_APPS;
|
||||
setter.setFloat(mLauncher.getAppsView(),
|
||||
ActivityAllAppsContainerView.BOTTOM_SHEET_ALPHA, hasAllAppsContent ? 1 : 0,
|
||||
config.getInterpolator(ANIM_ALL_APPS_BOTTOM_SHEET_FADE, INSTANT));
|
||||
|
||||
boolean shouldProtectHeader = !config.hasAnimationFlag(StateAnimationConfig.SKIP_SCRIM)
|
||||
&& (ALL_APPS == state || mLauncher.getStateManager().getState() == ALL_APPS);
|
||||
mScrimView.setDrawingController(shouldProtectHeader ? mAppsView : null);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ public class SecondaryLauncherAllAppsContainerView extends
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateBackground(DeviceProfile deviceProfile) {}
|
||||
protected void updateBackgroundVisibility(DeviceProfile deviceProfile) {}
|
||||
|
||||
@Override
|
||||
public boolean isInAllApps() {
|
||||
|
||||
@@ -118,9 +118,13 @@ public final class FeatureFlags {
|
||||
|
||||
// TODO(Block 4): Cleanup flags
|
||||
public static final BooleanFlag ENABLE_FLOATING_SEARCH_BAR =
|
||||
getReleaseFlag(270390286, "ENABLE_FLOATING_SEARCH_BAR", DISABLED,
|
||||
getReleaseFlag(268388460, "ENABLE_FLOATING_SEARCH_BAR", DISABLED,
|
||||
"Keep All Apps search bar at the bottom (but above keyboard if open)");
|
||||
|
||||
public static final BooleanFlag ENABLE_ALL_APPS_FROM_OVERVIEW =
|
||||
getDebugFlag(275132633, "ENABLE_ALL_APPS_FROM_OVERVIEW", DISABLED,
|
||||
"Allow entering All Apps from Overview (e.g. long swipe up from app)");
|
||||
|
||||
public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = getReleaseFlag(
|
||||
270394468, "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", ENABLED,
|
||||
"Enable option to show keyboard when going to all-apps");
|
||||
|
||||
@@ -65,7 +65,8 @@ public class StateAnimationConfig {
|
||||
ANIM_OVERVIEW_ACTIONS_FADE,
|
||||
ANIM_WORKSPACE_PAGE_TRANSLATE_X,
|
||||
ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN,
|
||||
ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE
|
||||
ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE,
|
||||
ANIM_ALL_APPS_BOTTOM_SHEET_FADE
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface AnimType {}
|
||||
@@ -88,8 +89,9 @@ public class StateAnimationConfig {
|
||||
public static final int ANIM_WORKSPACE_PAGE_TRANSLATE_X = 15;
|
||||
public static final int ANIM_OVERVIEW_SPLIT_SELECT_FLOATING_TASK_TRANSLATE_OFFSCREEN = 17;
|
||||
public static final int ANIM_OVERVIEW_SPLIT_SELECT_INSTRUCTIONS_FADE = 18;
|
||||
public static final int ANIM_ALL_APPS_BOTTOM_SHEET_FADE = 19;
|
||||
|
||||
private static final int ANIM_TYPES_COUNT = 19;
|
||||
private static final int ANIM_TYPES_COUNT = 20;
|
||||
|
||||
protected final Interpolator[] mInterpolators = new Interpolator[ANIM_TYPES_COUNT];
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ import static com.android.launcher3.anim.Interpolators.EMPHASIZED_DECELERATE;
|
||||
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
|
||||
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.clampToProgress;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_BOTTOM_SHEET_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE;
|
||||
@@ -32,11 +34,14 @@ import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_SCALE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_WORKSPACE_TRANSLATE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
@@ -269,4 +274,44 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
|
||||
: ALL_APPS_VERTICAL_PROGRESS_ATOMIC);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies Animation config values for transition from overview to all apps.
|
||||
*
|
||||
* @param threshold progress at which all apps will open upon release
|
||||
*/
|
||||
public static void applyOverviewToAllAppsAnimConfig(
|
||||
DeviceProfile deviceProfile, StateAnimationConfig config, float threshold) {
|
||||
config.userControlled = true;
|
||||
config.animFlags = SKIP_OVERVIEW;
|
||||
if (deviceProfile.isTablet) {
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE, INSTANT);
|
||||
config.setInterpolator(ANIM_SCRIM_FADE, ALL_APPS_SCRIM_RESPONDER);
|
||||
// The fact that we end on Workspace is not very ideal, but since we do, fade it in at
|
||||
// the end of the transition. Don't scale/translate it.
|
||||
config.setInterpolator(ANIM_WORKSPACE_FADE, clampToProgress(LINEAR, 0.8f, 1));
|
||||
config.setInterpolator(ANIM_WORKSPACE_SCALE, INSTANT);
|
||||
config.setInterpolator(ANIM_WORKSPACE_TRANSLATE, INSTANT);
|
||||
} else {
|
||||
// Remove scrim for this transition.
|
||||
config.setInterpolator(ANIM_SCRIM_FADE, progress -> 0);
|
||||
|
||||
// For now, pop the background panel in at full opacity at the threshold.
|
||||
config.setInterpolator(ANIM_ALL_APPS_BOTTOM_SHEET_FADE,
|
||||
thresholdInterpolator(threshold, INSTANT));
|
||||
|
||||
// Fade the apps in when the scrim normally does, so it's apparent sooner what is
|
||||
// happening (in this case we are fading them on top of the background panel).
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE,
|
||||
thresholdInterpolator(threshold, SCRIM_FADE_MANUAL));
|
||||
|
||||
config.setInterpolator(ANIM_VERTICAL_PROGRESS,
|
||||
thresholdInterpolator(threshold, ALL_APPS_VERTICAL_PROGRESS_MANUAL));
|
||||
}
|
||||
}
|
||||
|
||||
/** Creates an interpolator that is 0 until the threshold, then follows given interpolator. */
|
||||
private static Interpolator thresholdInterpolator(float threshold, Interpolator interpolator) {
|
||||
return progress -> progress <= threshold ? 0 : interpolator.getInterpolation(progress);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user