Support swiping between states

- Swiping down on hotseat from overview goes to workspace
- Can swipe up through overview to get to all apps

Bug: 76449024
Change-Id: I7f76d92da976e268cc2a97e55746cca4603e6620
This commit is contained in:
Tony Wickham 2018-03-28 11:21:49 -07:00 committed by Tony
parent 86d7b2d81d
commit 274b9529ff
5 changed files with 65 additions and 30 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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() {

View File

@ -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;
}

View File

@ -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();