diff --git a/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java index 23add9595c..3622fc4250 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java @@ -37,11 +37,15 @@ public class LandscapeEdgeSwipeController extends AbstractStateChangeTouchContro @Override protected int getSwipeDirection(MotionEvent ev) { - mFromState = NORMAL; - mToState = OVERVIEW; return SwipeDetector.DIRECTION_BOTH; } + @Override + protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) { + boolean draggingFromNav = mLauncher.getDeviceProfile().isSeascape() != isDragTowardPositive; + return draggingFromNav ? OVERVIEW : NORMAL; + } + @Override protected float getShiftRange() { return mLauncher.getDragLayer().getWidth(); diff --git a/quickstep/src/com/android/launcher3/uioverrides/LandscapeStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/LandscapeStatesTouchController.java index 720b20ac1b..355b88d910 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/LandscapeStatesTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/LandscapeStatesTouchController.java @@ -58,8 +58,9 @@ public class LandscapeStatesTouchController extends PortraitStatesTouchControlle } } - protected LauncherState getTargetState() { - if (mLauncher.isInState(ALL_APPS)) { + @Override + protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) { + if (fromState == ALL_APPS) { // Should swipe down go to OVERVIEW instead? return TouchInteractionService.isConnected() ? mLauncher.getStateManager().getLastState() : NORMAL; diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java index 7d9cce49a2..bdbdd8f76e 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java @@ -44,10 +44,10 @@ import com.android.quickstep.util.SysuiEventLogger; */ public class PortraitStatesTouchController extends AbstractStateChangeTouchController { - private static final float TOTAL_DISTANCE_MULTIPLIER = 2f; + private static final float TOTAL_DISTANCE_MULTIPLIER = 3f; private static final float LINEAR_SCALE_LIMIT = 1 / TOTAL_DISTANCE_MULTIPLIER; - // Much be greater than LINEAR_SCALE_LIMIT; + // Must be greater than LINEAR_SCALE_LIMIT; private static final float MAXIMUM_DISTANCE_FACTOR = 0.9f; // Maximum amount to overshoot. @@ -129,29 +129,26 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE; mStartContainerType = ContainerType.HOTSEAT; } else if (mLauncher.isInState(OVERVIEW)) { - directionsToDetectScroll = SwipeDetector.DIRECTION_POSITIVE; + directionsToDetectScroll = SwipeDetector.DIRECTION_BOTH; mStartContainerType = ContainerType.TASKSWITCHER; } else { return 0; } - mFromState = mLauncher.getStateManager().getState(); - mToState = getTargetState(); - if (mFromState == mToState) { - return 0; - } return directionsToDetectScroll; } - protected LauncherState getTargetState() { - if (mLauncher.isInState(ALL_APPS)) { + @Override + protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) { + if (fromState == ALL_APPS) { // Should swipe down go to OVERVIEW instead? return TouchInteractionService.isConnected() ? mLauncher.getStateManager().getLastState() : NORMAL; - } else if (mLauncher.isInState(OVERVIEW)) { - return ALL_APPS; - } else { + } else if (fromState == OVERVIEW) { + return isDragTowardPositive ? ALL_APPS : NORMAL; + } else if (isDragTowardPositive) { return TouchInteractionService.isConnected() ? OVERVIEW : ALL_APPS; } + return fromState; } private AnimatorSetBuilder getNormalToOverviewAnimation() { diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index a22f450e3b..4e905fa50a 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -19,7 +19,6 @@ import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelo import android.animation.Animator; import android.animation.AnimatorListenerAdapter; -import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.util.Log; import android.view.MotionEvent; @@ -58,6 +57,7 @@ public abstract class AbstractStateChangeTouchController extends AnimatorListene private float mStartProgress; // Ratio of transition process [0, 1] to drag displacement (px) private float mProgressMultiplier; + private float mDisplacementShift; public AbstractStateChangeTouchController(Launcher l, SwipeDetector.Direction dir) { mLauncher = l; @@ -68,7 +68,7 @@ public abstract class AbstractStateChangeTouchController extends AnimatorListene /** * Initializes the {@code mFromState} and {@code mToState} and swipe direction to use for - * the detector. In can of disabling swipe, return 0. + * the detector. In case of disabling swipe, return 0. */ protected abstract int getSwipeDirection(MotionEvent ev); @@ -122,16 +122,36 @@ public abstract class AbstractStateChangeTouchController extends AnimatorListene return mLauncher.getAllAppsController().getShiftRange(); } + protected abstract LauncherState getTargetState(LauncherState fromState, + boolean isDragTowardPositive); + protected abstract float initCurrentAnimation(); + private boolean reinitCurrentAnimation(boolean reachedToState, boolean isDragTowardPositive) { + LauncherState newFromState = mFromState == null ? mLauncher.getStateManager().getState() + : reachedToState ? mToState : mFromState; + LauncherState newToState = getTargetState(newFromState, isDragTowardPositive); + + if (newFromState == mFromState && newToState == mToState || (newFromState == newToState)) { + return false; + } + + mFromState = newFromState; + mToState = newToState; + + mStartProgress = 0; + mProgressMultiplier = initCurrentAnimation(); + mCurrentAnimation.getTarget().addListener(this); + mCurrentAnimation.dispatchOnStart(); + return true; + } + @Override public void onDragStart(boolean start) { if (mCurrentAnimation == null) { - mStartProgress = 0; - mProgressMultiplier = initCurrentAnimation(); - - mCurrentAnimation.getTarget().addListener(this); - mCurrentAnimation.dispatchOnStart(); + mFromState = mToState = null; + reinitCurrentAnimation(false, mDetector.wasInitialTouchPositive()); + mDisplacementShift = 0; } else { mCurrentAnimation.pause(); mStartProgress = mCurrentAnimation.getProgressFraction(); @@ -140,8 +160,19 @@ public abstract class AbstractStateChangeTouchController extends AnimatorListene @Override public boolean onDrag(float displacement, float velocity) { - float deltaProgress = mProgressMultiplier * displacement; - updateProgress(deltaProgress + mStartProgress); + float deltaProgress = mProgressMultiplier * (displacement - mDisplacementShift); + float progress = deltaProgress + mStartProgress; + updateProgress(progress); + boolean isDragTowardPositive = (displacement - mDisplacementShift) < 0; + if (progress <= 0) { + if (reinitCurrentAnimation(false, isDragTowardPositive)) { + mDisplacementShift = displacement; + } + } else if (progress >= 1) { + if (reinitCurrentAnimation(true, isDragTowardPositive)) { + mDisplacementShift = displacement; + } + } return true; } diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsSwipeController.java b/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsSwipeController.java index e495477f57..c97c3ccecb 100644 --- a/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsSwipeController.java +++ b/src_ui_overrides/com/android/launcher3/uioverrides/AllAppsSwipeController.java @@ -7,6 +7,7 @@ import android.view.MotionEvent; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherState; import com.android.launcher3.touch.AbstractStateChangeTouchController; import com.android.launcher3.touch.SwipeDetector; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; @@ -43,18 +44,19 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController { protected int getSwipeDirection(MotionEvent ev) { if (mLauncher.isInState(ALL_APPS)) { mStartContainerType = ContainerType.ALLAPPS; - mFromState = ALL_APPS; - mToState = NORMAL; return SwipeDetector.DIRECTION_NEGATIVE; } else { - mFromState = NORMAL; - mToState = ALL_APPS; mStartContainerType = mLauncher.getDragLayer().isEventOverHotseat(ev) ? ContainerType.HOTSEAT : ContainerType.WORKSPACE; return SwipeDetector.DIRECTION_POSITIVE; } } + @Override + protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) { + return fromState == ALL_APPS ? NORMAL : ALL_APPS; + } + @Override protected float initCurrentAnimation() { float range = getShiftRange();