diff options
author | Tony Wickham <twickham@google.com> | 2018-05-09 16:00:14 -0700 |
---|---|---|
committer | Tony Wickham <twickham@google.com> | 2018-05-16 13:47:20 -0700 |
commit | 0f640b6c1b1f600f4c8c39cb915f7a02603f311a (patch) | |
tree | 7556d6c249eb22d25f0dc16b3ec29b4c4ef7f2fd /src | |
parent | 61745e17c75612d97b62313723831e51d62191bf (diff) | |
download | android_packages_apps_Trebuchet-0f640b6c1b1f600f4c8c39cb915f7a02603f311a.tar.gz android_packages_apps_Trebuchet-0f640b6c1b1f600f4c8c39cb915f7a02603f311a.tar.bz2 android_packages_apps_Trebuchet-0f640b6c1b1f600f4c8c39cb915f7a02603f311a.zip |
Make fling thresholds consistent
There are 3 places we can block a fling:
- Swiping from home to all apps (through overview)
- Swiping from an app to all apps (through overview)
- Dismissing a task (in the same gesture that started by swiping down)
In all of these cases, we block the fling when crossing the threshold
to a new state (e.g. OVERVIEW), but unblock if the user pauses their
drag. With this change, the logic is consistent:
- Unblock the fling after pausing a short amount of time
- If a fling was blocked, increase the settling duration based on
velocity
Bug: 78089840
Bug: 78658678
Change-Id: I5ef52b74229418b867b26c3c6d3db2cf6e48914b
Diffstat (limited to 'src')
3 files changed, 78 insertions, 22 deletions
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java index 9869fdf7e..03ffded72 100644 --- a/src/com/android/launcher3/LauncherAnimUtils.java +++ b/src/com/android/launcher3/LauncherAnimUtils.java @@ -39,6 +39,9 @@ public class LauncherAnimUtils { public static final int SPRING_LOADED_TRANSITION_MS = 150; public static final int SPRING_LOADED_EXIT_DELAY = 500; + // The progress of an animation to all apps must be at least this far along to snap to all apps. + public static final float MIN_PROGRESS_TO_ALL_APPS = 0.5f; + static WeakHashMap<Animator, Object> sAnimators = new WeakHashMap<Animator, Object>(); static Animator.AnimatorListener sEndAnimListener = new Animator.AnimatorListener() { public void onAnimationStart(Animator animation) { @@ -165,16 +168,8 @@ public class LauncherAnimUtils { } }; - public static final Property<View, Float> ELEVATION = - new Property<View, Float>(Float.class, "elevation") { - @Override - public Float get(View view) { - return view.getElevation(); - } - - @Override - public void set(View view, Float elevation) { - view.setElevation(elevation); - } - }; + /** Increase the duration if we prevented the fling, as we are going against a high velocity. */ + public static int blockedFlingDurationFactor(float velocity) { + return (int) Utilities.boundToRange(Math.abs(velocity) / 2, 2f, 6f); + } } diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index 6e48c3641..087549e2e 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -15,6 +15,7 @@ */ package com.android.launcher3.touch; +import static com.android.launcher3.LauncherAnimUtils.MIN_PROGRESS_TO_ALL_APPS; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; @@ -32,6 +33,7 @@ import android.view.HapticFeedbackConstants; import android.view.MotionEvent; import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager.AnimationComponents; import com.android.launcher3.LauncherStateManager.AnimationConfig; @@ -43,6 +45,7 @@ import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; +import com.android.launcher3.util.FlingBlockCheck; import com.android.launcher3.util.PendingAnimation; import com.android.launcher3.util.TouchController; @@ -80,7 +83,7 @@ public abstract class AbstractStateChangeTouchController private float mProgressMultiplier; private float mDisplacementShift; private boolean mCanBlockFling; - private boolean mBlockFling; + private FlingBlockCheck mFlingBlockCheck = new FlingBlockCheck(); private AnimatorSet mAtomicAnim; private boolean mPassedOverviewAtomicThreshold; @@ -241,7 +244,7 @@ public abstract class AbstractStateChangeTouchController mStartProgress = mCurrentAnimation.getProgressFraction(); } mCanBlockFling = mFromState == NORMAL; - mBlockFling = false; + mFlingBlockCheck.unblockFling(); } @Override @@ -253,16 +256,19 @@ public abstract class AbstractStateChangeTouchController if (progress <= 0) { if (reinitCurrentAnimation(false, isDragTowardPositive)) { mDisplacementShift = displacement; - mBlockFling = mCanBlockFling; + if (mCanBlockFling) { + mFlingBlockCheck.blockFling(); + } } } else if (progress >= 1) { if (reinitCurrentAnimation(true, isDragTowardPositive)) { mDisplacementShift = displacement; - mBlockFling = mCanBlockFling; + if (mCanBlockFling) { + mFlingBlockCheck.blockFling(); + } } - } else if (Math.abs(velocity) < SwipeDetector.RELEASE_VELOCITY_PX_MS) { - // We prevent flinging after passing a state, but allow it if the user pauses briefly. - mBlockFling = false; + } else { + mFlingBlockCheck.onEvent(); } return true; @@ -325,7 +331,7 @@ public abstract class AbstractStateChangeTouchController final LauncherState targetState; final float progress = mCurrentAnimation.getProgressFraction(); - boolean blockedFling = fling && mBlockFling; + boolean blockedFling = fling && mFlingBlockCheck.isBlocked(); if (blockedFling) { fling = false; } @@ -338,14 +344,17 @@ public abstract class AbstractStateChangeTouchController // snap to top or bottom using the release velocity } else { logAction = Touch.SWIPE; - targetState = (progress > SUCCESS_TRANSITION_PROGRESS) ? mToState : mFromState; + float successProgress = mToState == ALL_APPS + ? MIN_PROGRESS_TO_ALL_APPS : SUCCESS_TRANSITION_PROGRESS; + targetState = (progress > successProgress) ? mToState : mFromState; } final float endProgress; final float startProgress; final long duration; // Increase the duration if we prevented the fling, as we are going against a high velocity. - final long durationMultiplier = blockedFling && targetState == mFromState ? 6 : 1; + final int durationMultiplier = blockedFling && targetState == mFromState + ? LauncherAnimUtils.blockedFlingDurationFactor(velocity) : 1; if (targetState == mToState) { endProgress = 1; diff --git a/src/com/android/launcher3/util/FlingBlockCheck.java b/src/com/android/launcher3/util/FlingBlockCheck.java new file mode 100644 index 000000000..f9575b97a --- /dev/null +++ b/src/com/android/launcher3/util/FlingBlockCheck.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.util; + +import android.os.SystemClock; + +/** + * Determines whether a fling should be blocked. Currently we block flings when crossing thresholds + * to new states, and unblock after a short duration. + */ +public class FlingBlockCheck { + // Allow flinging to a new state after waiting this many milliseconds. + private static final long UNBLOCK_FLING_PAUSE_DURATION = 200; + + private boolean mBlockFling; + private long mBlockFlingTime; + + public void blockFling() { + mBlockFling = true; + mBlockFlingTime = SystemClock.uptimeMillis(); + } + + public void unblockFling() { + mBlockFling = false; + mBlockFlingTime = 0; + } + + public void onEvent() { + // We prevent flinging after passing a state, but allow it if the user pauses briefly. + if (SystemClock.uptimeMillis() - mBlockFlingTime >= UNBLOCK_FLING_PAUSE_DURATION) { + mBlockFling = false; + } + } + + public boolean isBlocked() { + return mBlockFling; + } +} |