summaryrefslogtreecommitdiffstats
path: root/quickstep
diff options
context:
space:
mode:
authorTony Wickham <twickham@google.com>2019-04-05 13:52:35 -0700
committerTony Wickham <twickham@google.com>2019-04-09 10:53:24 -0700
commit9791bd1555b2143fcc39830cdc555aa51114f4b0 (patch)
tree4ccb461497a01766d21b339e0ecb72a9c7feff11 /quickstep
parent2a059c7802c68ffbccbde00b6036b8cbd2b04a7d (diff)
downloadandroid_packages_apps_Trebuchet-9791bd1555b2143fcc39830cdc555aa51114f4b0.tar.gz
android_packages_apps_Trebuchet-9791bd1555b2143fcc39830cdc555aa51114f4b0.tar.bz2
android_packages_apps_Trebuchet-9791bd1555b2143fcc39830cdc555aa51114f4b0.zip
Swipe up on nav bar to go home from -1 and widgets
More specifically, any window (e.g. qsb search) or AbstractFloatingView. NavBarToHomeTouchController now implements TouchController directly instead of AbstractStateChangeTouchController, as it not only dealing with launcher states. This makes it easier to override intercept logic to handle cases like not having window focus, for example. AbstractFloatingViews can createHintCloseAnim() to play an animation hinting that it is about to be closed by swiping up. Widgets sheets use this to pull back similar to the all apps transition to home. Bug: 129976669 Change-Id: Ie157b978d9f1ee36d5fd32cea72ec02ce40878c0
Diffstat (limited to 'quickstep')
-rw-r--r--quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java182
-rw-r--r--quickstep/res/values/dimens.xml3
2 files changed, 136 insertions, 49 deletions
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index 673beff85..21ddfc015 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -15,74 +15,131 @@
*/
package com.android.launcher3.uioverrides.touchcontrollers;
+import static android.view.View.TRANSLATION_X;
+
+import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
+import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
+import static com.android.launcher3.touch.AbstractStateChangeTouchController.SUCCESS_TRANSITION_PROGRESS;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.view.MotionEvent;
-import android.view.View;
import android.view.animation.Interpolator;
+import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager.AnimationConfig;
+import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.AllAppsTransitionController;
+import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.AnimatorSetBuilder;
import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.SwipeDetector;
import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Command;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.launcher3.util.TouchController;
import com.android.quickstep.views.RecentsView;
/**
- * Handles swiping up on the nav bar to go home from overview or all apps.
+ * Handles swiping up on the nav bar to go home from launcher, e.g. overview or all apps.
*/
-public class NavBarToHomeTouchController extends AbstractStateChangeTouchController {
+public class NavBarToHomeTouchController implements TouchController, SwipeDetector.Listener {
private static final Interpolator PULLBACK_INTERPOLATOR = DEACCEL_3;
+ private final Launcher mLauncher;
+ private final SwipeDetector mSwipeDetector;
+ private final float mPullbackDistance;
+
+ private boolean mNoIntercept;
+ private LauncherState mStartState;
+ private LauncherState mEndState = NORMAL;
+ private AnimatorPlaybackController mCurrentAnimation;
+
public NavBarToHomeTouchController(Launcher launcher) {
- super(launcher, SwipeDetector.VERTICAL);
+ mLauncher = launcher;
+ mSwipeDetector = new SwipeDetector(mLauncher, this, SwipeDetector.VERTICAL);
+ mPullbackDistance = mLauncher.getResources().getDimension(R.dimen.home_pullback_distance);
}
@Override
- protected boolean canInterceptTouch(MotionEvent ev) {
+ public final boolean onControllerInterceptTouchEvent(MotionEvent ev) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ mStartState = mLauncher.getStateManager().getState();
+ mNoIntercept = !canInterceptTouch(ev);
+ if (mNoIntercept) {
+ return false;
+ }
+ mSwipeDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_POSITIVE, false);
+ }
+
+ if (mNoIntercept) {
+ return false;
+ }
+
+ onControllerTouchEvent(ev);
+ return mSwipeDetector.isDraggingOrSettling();
+ }
+
+ private boolean canInterceptTouch(MotionEvent ev) {
boolean cameFromNavBar = (ev.getEdgeFlags() & Utilities.EDGE_NAV_BAR) != 0;
- return cameFromNavBar && (mLauncher.isInState(OVERVIEW) || mLauncher.isInState(ALL_APPS));
+ if (!cameFromNavBar) {
+ return false;
+ }
+ if (mStartState == OVERVIEW || mStartState == ALL_APPS) {
+ return true;
+ }
+ if (!mLauncher.hasWindowFocus()) {
+ return true;
+ }
+ if (AbstractFloatingView.getTopOpenView(mLauncher) != null) {
+ return true;
+ }
+ return false;
}
@Override
- protected LauncherState getTargetState(LauncherState fromState, boolean isDragTowardPositive) {
- return isDragTowardPositive ? NORMAL : fromState;
+ public final boolean onControllerTouchEvent(MotionEvent ev) {
+ return mSwipeDetector.onTouchEvent(ev);
+ }
+
+ private float getShiftRange() {
+ return mLauncher.getDeviceProfile().heightPx;
}
@Override
- protected float initCurrentAnimation(int animComponents) {
+ public void onDragStart(boolean start) {
+ initCurrentAnimation();
+ }
+
+ private void initCurrentAnimation() {
long accuracy = (long) (getShiftRange() * 2);
- final AnimatorSet anim;
- if (mFromState == OVERVIEW) {
- anim = new AnimatorSet();
+ final AnimatorSet anim = new AnimatorSet();
+ if (mStartState == OVERVIEW) {
RecentsView recentsView = mLauncher.getOverviewPanel();
- float pullbackDistance = recentsView.getPaddingStart() / 2;
+ float pullbackDist = mPullbackDistance;
if (!recentsView.isRtl()) {
- pullbackDistance = -pullbackDistance;
+ pullbackDist = -pullbackDist;
}
- anim.play(ObjectAnimator.ofFloat(recentsView, View.TRANSLATION_X, pullbackDistance));
- anim.setInterpolator(PULLBACK_INTERPOLATOR);
- } else { // if (mFromState == ALL_APPS)
+ Animator pullback = ObjectAnimator.ofFloat(recentsView, TRANSLATION_X, pullbackDist);
+ pullback.setInterpolator(PULLBACK_INTERPOLATOR);
+ anim.play(pullback);
+ } else if (mStartState == ALL_APPS) {
AnimatorSetBuilder builder = new AnimatorSetBuilder();
AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
- final float pullbackDistance = mLauncher.getDeviceProfile().allAppsIconSizePx / 2;
Animator allAppsProgress = ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS,
- -pullbackDistance / allAppsController.getShiftRange());
+ -mPullbackDistance / allAppsController.getShiftRange());
allAppsProgress.setInterpolator(PULLBACK_INTERPOLATOR);
builder.play(allAppsProgress);
// Slightly fade out all apps content to further distinguish from scrolling.
@@ -90,52 +147,79 @@ public class NavBarToHomeTouchController extends AbstractStateChangeTouchControl
.mapToProgress(PULLBACK_INTERPOLATOR, 0, 0.5f));
AnimationConfig config = new AnimationConfig();
config.duration = accuracy;
- allAppsController.setAlphas(mToState.getVisibleElements(mLauncher), config, builder);
- anim = builder.build();
+ allAppsController.setAlphas(mEndState.getVisibleElements(mLauncher), config, builder);
+ anim.play(builder.build());
+ }
+ AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mLauncher);
+ if (topView != null) {
+ Animator hintCloseAnim = topView.createHintCloseAnim(mPullbackDistance);
+ if (hintCloseAnim != null) {
+ hintCloseAnim.setInterpolator(PULLBACK_INTERPOLATOR);
+ anim.play(hintCloseAnim);
+ }
}
anim.setDuration(accuracy);
mCurrentAnimation = AnimatorPlaybackController.wrap(anim, accuracy, this::clearState);
- return -1 / getShiftRange();
+ }
+
+ private void clearState() {
+ mCurrentAnimation = null;
+ mSwipeDetector.finishedScrolling();
+ mSwipeDetector.setDetectableScrollConditions(0, false);
}
@Override
- public void onDragStart(boolean start) {
- super.onDragStart(start);
- mStartContainerType = LauncherLogProto.ContainerType.NAVBAR;
+ public boolean onDrag(float displacement) {
+ // Only allow swipe up.
+ displacement = Math.min(0, displacement);
+ float progress = Utilities.getProgress(displacement, 0, getShiftRange());
+ mCurrentAnimation.setPlayFraction(progress);
+ return true;
}
@Override
public void onDragEnd(float velocity, boolean fling) {
final int logAction = fling ? Touch.FLING : Touch.SWIPE;
- float interpolatedProgress = PULLBACK_INTERPOLATOR.getInterpolation(
- mCurrentAnimation.getProgressFraction());
- if (interpolatedProgress >= SUCCESS_TRANSITION_PROGRESS || velocity < 0 && fling) {
- mLauncher.getStateManager().goToState(mToState, true,
- () -> onSwipeInteractionCompleted(mToState, logAction));
+ float progress = mCurrentAnimation.getProgressFraction();
+ float interpolatedProgress = PULLBACK_INTERPOLATOR.getInterpolation(progress);
+ boolean success = interpolatedProgress >= SUCCESS_TRANSITION_PROGRESS
+ || (velocity < 0 && fling);
+ if (success) {
+ mLauncher.getStateManager().goToState(mEndState, true,
+ () -> onSwipeInteractionCompleted(mEndState));
+ if (mStartState != mEndState) {
+ logStateChange(mStartState.containerType, logAction);
+ }
+ AbstractFloatingView topOpenView = AbstractFloatingView.getTopOpenView(mLauncher);
+ if (topOpenView != null) {
+ AbstractFloatingView.closeAllOpenViews(mLauncher);
+ logStateChange(topOpenView.getLogContainerType(), logAction);
+ }
} else {
// Quickly return to the state we came from (we didn't move far).
- AnimatorPlaybackController anim = mLauncher.getStateManager()
- .createAnimationToNewWorkspace(mFromState, 80);
- anim.setEndAction(() -> onSwipeInteractionCompleted(mFromState, logAction));
- anim.start();
+ ValueAnimator anim = mCurrentAnimation.getAnimationPlayer();
+ anim.setFloatValues(progress, 0);
+ anim.addListener(new AnimationSuccessListener() {
+ @Override
+ public void onAnimationSuccess(Animator animator) {
+ onSwipeInteractionCompleted(mStartState);
+ }
+ });
+ anim.setDuration(80).start();
}
- mCurrentAnimation.dispatchOnCancel();
- }
-
- @Override
- protected int getDirectionForLog() {
- return LauncherLogProto.Action.Direction.UP;
}
- @Override
- protected boolean goingBetweenNormalAndOverview(LauncherState fromState,
- LauncherState toState) {
- // We don't want to create an atomic animation to/from overview.
- return false;
+ private void onSwipeInteractionCompleted(LauncherState targetState) {
+ clearState();
+ mLauncher.getStateManager().goToState(targetState, false /* animated */);
}
- @Override
- protected int getLogContainerTypeForNormalState() {
- return LauncherLogProto.ContainerType.NAVBAR;
+ private void logStateChange(int startContainerType, int logAction) {
+ mLauncher.getUserEventDispatcher().logStateChangeAction(logAction,
+ LauncherLogProto.Action.Direction.UP,
+ LauncherLogProto.ContainerType.NAVBAR,
+ startContainerType,
+ mEndState.containerType,
+ mLauncher.getWorkspace().getCurrentPage());
}
}
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 97f2de762..9e1833c75 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -68,4 +68,7 @@
<!-- Assistant Gestures -->
<dimen name="gestures_assistant_size">28dp</dimen>
<dimen name="gestures_assistant_drag_threshold">70dp</dimen>
+
+ <!-- Distance to move elements when swiping up to go home from launcher -->
+ <dimen name="home_pullback_distance">28dp</dimen>
</resources>