Remove quick switch and improve quick scrub
- Hide hotseat and center recents vertically during quick scrub
- Don't animate the state change if launcher wasn't already visible, but still
wait until the window animation completes before scrubbing past the next app
- Change interpolator of window as it scales offscreen during quick scrub, so that
it gets out of the way faster and you can see the motion of the next app taking
its place
- Remove haptic when snapping to task when quick scrub starts (there's already a
haptic from the home button)
Bug: 70180755
Change-Id: I83f25bc8b791da0676c13fd62698e1f486dc016f
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 6e56055..e414fa0 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
index 7c08ff6..2626e7c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
@@ -88,8 +88,10 @@
}
@Override
- public float getOverviewTranslationFactor(Launcher launcher) {
- return 0;
+ public float[] getOverviewTranslationFactor(Launcher launcher) {
+ // Keep the same translation as in overview, so that we don't slide around when
+ // transitioning to All Apps.
+ return LauncherState.OVERVIEW.getOverviewTranslationFactor(launcher);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
index 6543e8c..99bf264 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
@@ -28,10 +28,8 @@
private static final int STATE_FLAGS = FLAG_SHOW_SCRIM | FLAG_DISABLE_RESTORE
| FLAG_DISABLE_INTERACTION | FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON;
- private static final boolean DEBUG_DIFFERENT_UI = false;
-
public FastOverviewState(int id) {
- super(id, QuickScrubController.QUICK_SWITCH_START_DURATION, STATE_FLAGS);
+ super(id, QuickScrubController.QUICK_SCRUB_START_DURATION, STATE_FLAGS);
}
@Override
@@ -48,9 +46,11 @@
@Override
public int getVisibleElements(Launcher launcher) {
- if (DEBUG_DIFFERENT_UI) {
- return NONE;
- }
- return super.getVisibleElements(launcher);
+ return NONE;
+ }
+
+ @Override
+ public float[] getOverviewTranslationFactor(Launcher launcher) {
+ return new float[] {0f, 0.5f};
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
index 68322b0..abbf45e 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -58,8 +58,8 @@
}
@Override
- public float getOverviewTranslationFactor(Launcher launcher) {
- return 0;
+ public float[] getOverviewTranslationFactor(Launcher launcher) {
+ return new float[] {0f, 0f};
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index ae747d8..b993c3c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -20,7 +20,8 @@
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_TRANSLATION;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled;
-import static com.android.quickstep.views.LauncherRecentsView.TRANSLATION_FACTOR;
+import static com.android.quickstep.views.LauncherRecentsView.TRANSLATION_X_FACTOR;
+import static com.android.quickstep.views.LauncherRecentsView.TRANSLATION_Y_FACTOR;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
@@ -50,7 +51,9 @@
public void setState(LauncherState state) {
mRecentsView.setAlpha(state.overviewUi ? 1 : 0);
updateVisibility(mRecentsView, isAccessibilityEnabled(mLauncher));
- mRecentsView.setTranslationFactor(state.getOverviewTranslationFactor(mLauncher));
+ float[] translationFactor = state.getOverviewTranslationFactor(mLauncher);
+ mRecentsView.setTranslationXFactor(translationFactor[0]);
+ mRecentsView.setTranslationYFactor(translationFactor[1]);
if (state.overviewUi) {
mRecentsView.resetTaskVisuals();
}
@@ -73,8 +76,12 @@
}
PropertySetter setter = config.getProperSetter(builder);
- setter.setFloat(mRecentsView, TRANSLATION_FACTOR,
- toState.getOverviewTranslationFactor(mLauncher),
+ float[] translationFactor = toState.getOverviewTranslationFactor(mLauncher);
+ setter.setFloat(mRecentsView, TRANSLATION_X_FACTOR,
+ translationFactor[0],
+ builder.getInterpolator(ANIM_OVERVIEW_TRANSLATION, LINEAR));
+ setter.setFloat(mRecentsView, TRANSLATION_Y_FACTOR,
+ translationFactor[1],
builder.getInterpolator(ANIM_OVERVIEW_TRANSLATION, LINEAR));
setter.setViewAlpha(mRecentsView, toState.overviewUi ? 1 : 0, LINEAR);
diff --git a/quickstep/src/com/android/quickstep/MotionEventQueue.java b/quickstep/src/com/android/quickstep/MotionEventQueue.java
index 72f8301..8e6e4c7 100644
--- a/quickstep/src/com/android/quickstep/MotionEventQueue.java
+++ b/quickstep/src/com/android/quickstep/MotionEventQueue.java
@@ -19,9 +19,7 @@
import static android.view.MotionEvent.ACTION_MASK;
import static android.view.MotionEvent.ACTION_MOVE;
import static android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT;
-
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
-import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SWITCH;
import android.annotation.TargetApi;
import android.os.Build;
@@ -43,20 +41,18 @@
private static final int ACTION_VIRTUAL = ACTION_MASK - 1;
- private static final int ACTION_QUICK_SWITCH =
- ACTION_VIRTUAL | (1 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_QUICK_SCRUB_START =
- ACTION_VIRTUAL | (2 << ACTION_POINTER_INDEX_SHIFT);
+ ACTION_VIRTUAL | (1 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_QUICK_SCRUB_PROGRESS =
- ACTION_VIRTUAL | (3 << ACTION_POINTER_INDEX_SHIFT);
+ ACTION_VIRTUAL | (2 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_QUICK_SCRUB_END =
- ACTION_VIRTUAL | (4 << ACTION_POINTER_INDEX_SHIFT);
+ ACTION_VIRTUAL | (3 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_RESET =
- ACTION_VIRTUAL | (5 << ACTION_POINTER_INDEX_SHIFT);
+ ACTION_VIRTUAL | (4 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_DEFER_INIT =
- ACTION_VIRTUAL | (6 << ACTION_POINTER_INDEX_SHIFT);
+ ACTION_VIRTUAL | (5 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_SHOW_OVERVIEW_FROM_ALT_TAB =
- ACTION_VIRTUAL | (7 << ACTION_POINTER_INDEX_SHIFT);
+ ACTION_VIRTUAL | (6 << ACTION_POINTER_INDEX_SHIFT);
private final EventArray mEmptyArray = new EventArray();
private final Object mExecutionLock = new Object();
@@ -145,9 +141,6 @@
MotionEvent event = array.get(i);
if (event.getActionMasked() == ACTION_VIRTUAL) {
switch (event.getAction()) {
- case ACTION_QUICK_SWITCH:
- mConsumer.updateTouchTracking(INTERACTION_QUICK_SWITCH);
- break;
case ACTION_QUICK_SCRUB_START:
mConsumer.updateTouchTracking(INTERACTION_QUICK_SCRUB);
break;
@@ -195,10 +188,6 @@
queueNoPreProcess(MotionEvent.obtain(0, 0, action, progress, 0, 0));
}
- public void onQuickSwitch() {
- queueVirtualAction(ACTION_QUICK_SWITCH, 0);
- }
-
public void onQuickScrubStart() {
queueVirtualAction(ACTION_QUICK_SCRUB_START, 0);
}
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index 93eafe4..4877abb 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -21,7 +21,6 @@
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
import static android.view.MotionEvent.INVALID_POINTER_ID;
-
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW;
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index 986eb48..4f379e6 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -36,7 +36,7 @@
*/
public class QuickScrubController implements OnAlarmListener {
- public static final int QUICK_SWITCH_START_DURATION = 210;
+ public static final int QUICK_SCRUB_START_DURATION = 210;
private static final boolean ENABLE_AUTO_ADVANCE = true;
private static final int NUM_QUICK_SCRUB_SECTIONS = 3;
@@ -53,7 +53,6 @@
private int mQuickScrubSection;
private boolean mStartedFromHome;
private boolean mHasAlarmRun;
- private boolean mQuickSwitched;
private boolean mFinishedTransitionToQuickScrub;
public QuickScrubController(BaseActivity activity, RecentsView recentsView) {
@@ -70,7 +69,6 @@
mStartedFromHome = startingFromHome;
mQuickScrubSection = 0;
mHasAlarmRun = false;
- mQuickSwitched = false;
mFinishedTransitionToQuickScrub = false;
snapToNextTaskIfAvailable();
@@ -125,45 +123,21 @@
}
}
- public void onQuickSwitch() {
- mQuickSwitched = true;
- quickSwitchIfReady();
- }
-
public void onFinishedTransitionToQuickScrub() {
mFinishedTransitionToQuickScrub = true;
- quickSwitchIfReady();
- }
-
- /**
- * Immediately launches the current task (which we snapped to in onQuickScrubStart) if we've
- * gotten the onQuickSwitch callback and the transition to quick scrub has completed.
- */
- private void quickSwitchIfReady() {
- if (mQuickSwitched && mFinishedTransitionToQuickScrub) {
- onQuickScrubEnd();
- mActivity.getUserEventDispatcher().logActionOnControl(Touch.FLING,
- ControlType.QUICK_SCRUB_BUTTON, null, mStartedFromHome ?
- ContainerType.WORKSPACE : ContainerType.APP);
- }
}
public void snapToNextTaskIfAvailable() {
if (mInQuickScrub && mRecentsView.getChildCount() > 0) {
int toPage = mStartedFromHome ? 0 : mRecentsView.getNextPage() + 1;
- goToPageWithHaptic(toPage, QUICK_SWITCH_START_DURATION);
+ mRecentsView.snapToPage(toPage, QUICK_SCRUB_START_DURATION);
}
}
private void goToPageWithHaptic(int pageToGoTo) {
- goToPageWithHaptic(pageToGoTo, -1);
- }
-
- private void goToPageWithHaptic(int pageToGoTo, int overrideDuration) {
pageToGoTo = Utilities.boundToRange(pageToGoTo, 0, mRecentsView.getPageCount() - 1);
if (pageToGoTo != mRecentsView.getNextPage()) {
- int duration = overrideDuration > -1 ? overrideDuration
- : Math.abs(pageToGoTo - mRecentsView.getNextPage())
+ int duration = Math.abs(pageToGoTo - mRecentsView.getNextPage())
* QUICKSCRUB_SNAP_DURATION_PER_PAGE;
mRecentsView.snapToPage(pageToGoTo, duration);
mRecentsView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP,
diff --git a/quickstep/src/com/android/quickstep/TouchConsumer.java b/quickstep/src/com/android/quickstep/TouchConsumer.java
index 0554d9c..4e35159 100644
--- a/quickstep/src/com/android/quickstep/TouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/TouchConsumer.java
@@ -29,21 +29,14 @@
@FunctionalInterface
public interface TouchConsumer extends Consumer<MotionEvent> {
- static boolean isInteractionQuick(@InteractionType int interactionType) {
- return interactionType == INTERACTION_QUICK_SCRUB ||
- interactionType == INTERACTION_QUICK_SWITCH;
- }
-
@IntDef(flag = true, value = {
INTERACTION_NORMAL,
- INTERACTION_QUICK_SWITCH,
INTERACTION_QUICK_SCRUB
})
@Retention(RetentionPolicy.SOURCE)
@interface InteractionType {}
int INTERACTION_NORMAL = 0;
- int INTERACTION_QUICK_SWITCH = 1;
- int INTERACTION_QUICK_SCRUB = 2;
+ int INTERACTION_QUICK_SCRUB = 1;
default void reset() { }
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index bbbeb14..cc49dc7 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -21,9 +21,9 @@
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
import static android.view.MotionEvent.ACTION_POINTER_UP;
import static android.view.MotionEvent.ACTION_UP;
-
import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
@@ -55,8 +55,6 @@
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
-
/**
* Service connected by system-UI for handling touch interaction.
*/
@@ -112,12 +110,6 @@
}
@Override
- public void onQuickSwitch() {
- mEventQueue.onQuickSwitch();
- TraceHelper.endSection("SysUiBinder", "onQuickSwitch");
- }
-
- @Override
public void onQuickScrubStart() {
mEventQueue.onQuickScrubStart();
TraceHelper.partitionSection("SysUiBinder", "onQuickScrubStart");
@@ -160,7 +152,7 @@
}
@Override
- public void onQuickStep(MotionEvent motionEvent) throws RemoteException {
+ public void onQuickStep(MotionEvent motionEvent) {
}
};
@@ -336,14 +328,10 @@
if (mInvalidated) {
return;
}
- if (TouchConsumer.isInteractionQuick(interactionType)) {
+ if (interactionType == INTERACTION_QUICK_SCRUB) {
Runnable action = () -> {
- Runnable onComplete = null;
- if (interactionType == INTERACTION_QUICK_SWITCH) {
- onComplete = mQuickScrubController::onQuickSwitch;
- }
LauncherState fromState = mLauncher.getStateManager().getState();
- mLauncher.getStateManager().goToState(FAST_OVERVIEW, true, onComplete);
+ mLauncher.getStateManager().goToState(FAST_OVERVIEW, true);
mQuickScrubController.onQuickScrubStart(fromState == NORMAL);
};
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index f0bb367..25f2f87 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -15,11 +15,11 @@
*/
package com.android.quickstep;
-import static com.android.quickstep.QuickScrubController.QUICK_SWITCH_START_DURATION;
+import static com.android.launcher3.anim.Interpolators.ACCEL_2;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_START_DURATION;
import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
-import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SWITCH;
-import static com.android.quickstep.TouchConsumer.isInteractionQuick;
import static com.android.systemui.shared.recents.utilities.Utilities
.postAtFrontOfQueueAsynchronously;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
@@ -44,6 +44,7 @@
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver.OnDrawListener;
+import android.view.animation.Interpolator;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
@@ -101,9 +102,8 @@
// States for quick switch/scrub
private static final int STATE_SWITCH_TO_SCREENSHOT_COMPLETE = 1 << 10;
- private static final int STATE_QUICK_SWITCH = 1 << 11;
- private static final int STATE_QUICK_SCRUB_START = 1 << 12;
- private static final int STATE_QUICK_SCRUB_END = 1 << 13;
+ private static final int STATE_QUICK_SCRUB_START = 1 << 11;
+ private static final int STATE_QUICK_SCRUB_END = 1 << 12;
private static final int LAUNCHER_UI_STATES =
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_ACTIVITY_MULTIPLIER_COMPLETE
@@ -250,13 +250,10 @@
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
this::invalidateHandlerWithLauncher);
- mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_QUICK_SWITCH,
- this::onQuickInteractionStart);
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_QUICK_SCRUB_START,
- this::onQuickInteractionStart);
-
- mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SWITCH_TO_SCREENSHOT_COMPLETE
- | STATE_QUICK_SWITCH, this::switchToFinalAppAfterQuickSwitch);
+ this::onQuickScrubStart);
+ mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_QUICK_SCRUB_START
+ | STATE_SCALED_CONTROLLER_RECENTS, this::onFinishedTransitionToQuickScrub);
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SWITCH_TO_SCREENSHOT_COMPLETE
| STATE_QUICK_SCRUB_END, this::switchToFinalAppAfterQuickScrub);
}
@@ -365,7 +362,6 @@
mActivityControlHelper.prepareRecentsUI(mActivity, mWasLauncherAlreadyVisible);
AbstractFloatingView.closeAllOpenViews(activity, mWasLauncherAlreadyVisible);
-
if (mWasLauncherAlreadyVisible) {
mLauncherTransitionController = mActivityControlHelper
.createControllerForVisibleActivity(activity);
@@ -439,23 +435,16 @@
throw new IllegalArgumentException(
"Can't change interaction type from " + mInteractionType);
}
- if (!isInteractionQuick(interactionType)) {
+ if (interactionType != INTERACTION_QUICK_SCRUB) {
throw new IllegalArgumentException(
"Can't change interaction type to " + interactionType);
}
mInteractionType = interactionType;
- setStateOnUiThread(interactionType == INTERACTION_QUICK_SWITCH
- ? STATE_QUICK_SWITCH : STATE_QUICK_SCRUB_START);
+ setStateOnUiThread(STATE_QUICK_SCRUB_START);
// Start the window animation without waiting for launcher.
- animateToProgress(1f, QUICK_SWITCH_START_DURATION);
- }
-
- private void onQuickInteractionStart() {
- mActivityControlHelper.onQuickInteractionStart(mActivity,
- mWasLauncherAlreadyVisible || mGestureStarted);
- mQuickScrubController.onQuickScrubStart(false);
+ animateToProgress(1f, QUICK_SCRUB_START_DURATION);
}
@WorkerThread
@@ -488,7 +477,12 @@
if (mRecentsAnimationWrapper.controller != null) {
RectF currentRect;
synchronized (mTargetRect) {
- currentRect = mRectFEvaluator.evaluate(shift, mSourceRect, mTargetRect);
+ Interpolator interpolator = mInteractionType == INTERACTION_QUICK_SCRUB
+ ? ACCEL_2 : LINEAR;
+ float interpolated = interpolator.getInterpolation(shift);
+ currentRect = mRectFEvaluator.evaluate(interpolated, mSourceRect, mTargetRect);
+ // Stay lined up with the center of the target, since it moves for quick scrub.
+ currentRect.offset(mTargetRect.centerX() - currentRect.centerX(), 0);
}
mClipRect.left = (int) (mSourceWindowClipInsets.left * shift);
@@ -528,13 +522,12 @@
View firstTask = mRecentsView.getPageAt(0);
int scrollForFirstTask = mRecentsView.getScrollForPage(0);
int offsetFromFirstTask = (scrollForFirstTask - mRecentsView.getScrollX());
- if (offsetFromFirstTask != 0) {
- synchronized (mTargetRect) {
- mTargetRect.set(mInitialTargetRect);
- Utilities.scaleRectFAboutCenter(mTargetRect, firstTask.getScaleX());
- float offsetX = offsetFromFirstTask + firstTask.getTranslationX();
- mTargetRect.offset(offsetX, 0);
- }
+ synchronized (mTargetRect) {
+ mTargetRect.set(mInitialTargetRect);
+ Utilities.scaleRectFAboutCenter(mTargetRect, firstTask.getScaleX());
+ float offsetX = offsetFromFirstTask + firstTask.getTranslationX();
+ float offsetY = mRecentsView.getTranslationY();
+ mTargetRect.offset(offsetX, offsetY);
}
if (mRecentsAnimationWrapper.controller != null) {
@@ -764,21 +757,13 @@
reset();
}
- public void onQuickScrubEnd() {
- setStateOnUiThread(STATE_QUICK_SCRUB_END);
+ private void onQuickScrubStart() {
+ mActivityControlHelper.onQuickInteractionStart(mActivity, mWasLauncherAlreadyVisible);
+ mQuickScrubController.onQuickScrubStart(false);
}
- private void switchToFinalAppAfterQuickSwitch() {
- mQuickScrubController.onQuickSwitch();
- }
-
- private void switchToFinalAppAfterQuickScrub() {
- mQuickScrubController.onQuickScrubEnd();
-
- // Normally this is handled in reset(), but since we are still scrubbing after the
- // transition into recents, we need to defer the handler invalidation for quick scrub until
- // after the gesture ends
- setStateOnUiThread(STATE_HANDLER_INVALIDATED);
+ private void onFinishedTransitionToQuickScrub() {
+ mQuickScrubController.onFinishedTransitionToQuickScrub();
}
public void onQuickScrubProgress(float progress) {
@@ -791,6 +776,19 @@
mQuickScrubController.onQuickScrubProgress(progress);
}
+ public void onQuickScrubEnd() {
+ setStateOnUiThread(STATE_QUICK_SCRUB_END);
+ }
+
+ private void switchToFinalAppAfterQuickScrub() {
+ mQuickScrubController.onQuickScrubEnd();
+
+ // Normally this is handled in reset(), but since we are still scrubbing after the
+ // transition into recents, we need to defer the handler invalidation for quick scrub until
+ // after the gesture ends
+ setStateOnUiThread(STATE_HANDLER_INVALIDATED);
+ }
+
private void debugNewState(int stateFlag) {
if (!DEBUG_STATES) {
return;
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index d490f82..130d34c 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -47,17 +47,31 @@
@TargetApi(Build.VERSION_CODES.O)
public class LauncherRecentsView extends RecentsView<Launcher> implements Insettable {
- public static final FloatProperty<LauncherRecentsView> TRANSLATION_FACTOR =
- new FloatProperty<LauncherRecentsView>("translationFactor") {
+ public static final FloatProperty<LauncherRecentsView> TRANSLATION_X_FACTOR =
+ new FloatProperty<LauncherRecentsView>("translationXFactor") {
@Override
public void setValue(LauncherRecentsView view, float v) {
- view.setTranslationFactor(v);
+ view.setTranslationXFactor(v);
}
@Override
public Float get(LauncherRecentsView view) {
- return view.mTranslationFactor;
+ return view.mTranslationXFactor;
+ }
+ };
+
+ public static final FloatProperty<LauncherRecentsView> TRANSLATION_Y_FACTOR =
+ new FloatProperty<LauncherRecentsView>("translationYFactor") {
+
+ @Override
+ public void setValue(LauncherRecentsView view, float v) {
+ view.setTranslationYFactor(v);
+ }
+
+ @Override
+ public Float get(LauncherRecentsView view) {
+ return view.mTranslationYFactor;
}
};
@@ -67,7 +81,9 @@
private Matrix mFadeMatrix;
private boolean mScrimOnLeft;
- private float mTranslationFactor;
+ private float mTranslationXFactor;
+ private float mTranslationYFactor;
+ private Rect mPagePadding = new Rect();
public LauncherRecentsView(Context context) {
this(context, null);
@@ -91,6 +107,8 @@
setLayoutParams(lp);
setPadding(padding.left, padding.top, padding.right, 0);
+ mPagePadding.set(padding);
+ mPagePadding.top += getResources().getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
if (dp.isVerticalBarLayout()) {
boolean wasScrimOnLeft = mScrimOnLeft;
@@ -157,15 +175,25 @@
super.onLayout(changed, left, top, right, bottom);
int width = right - left;
- setTranslationX(mTranslationFactor * (mIsRtl ? -width : width));
+ setTranslationX(mTranslationXFactor * (mIsRtl ? -width : width));
+ setTranslationYFactor(mTranslationYFactor);
}
- public void setTranslationFactor(float translationFactor) {
- mTranslationFactor = translationFactor;
+ public void setTranslationXFactor(float translationFactor) {
+ mTranslationXFactor = translationFactor;
setTranslationX(translationFactor * (mIsRtl ? -getWidth() : getWidth()));
}
- public float getTranslationFactor() {
- return mTranslationFactor;
+ public float getTranslationXFactor() {
+ return mTranslationXFactor;
+ }
+
+ public void setTranslationYFactor(float translationFactor) {
+ mTranslationYFactor = translationFactor;
+ setTranslationY(mTranslationYFactor * (mPagePadding.bottom - mPagePadding.top));
+ }
+
+ public float getTranslationYFactor() {
+ return mTranslationYFactor;
}
}
diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java
index 5c16ca9..b1bf6ec 100644
--- a/src/com/android/launcher3/LauncherState.java
+++ b/src/com/android/launcher3/LauncherState.java
@@ -180,8 +180,13 @@
return new float[] {1, 0, 0};
}
- public float getOverviewTranslationFactor(Launcher launcher) {
- return 1;
+ /**
+ * Returns 2 floats designating how much to translate overview:
+ * X factor is based on width, e.g. 0 is fully onscreen and 1 is fully offscreen
+ * Y factor is based on padding, e.g. 0 is top aligned and 0.5 is centered vertically
+ */
+ public float[] getOverviewTranslationFactor(Launcher launcher) {
+ return new float[] {1f, 0f};
}
public void onStateEnabled(Launcher launcher) {