diff options
Diffstat (limited to 'quickstep')
-rw-r--r-- | quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java | 182 | ||||
-rw-r--r-- | quickstep/res/values/dimens.xml | 3 |
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> |