diff options
Diffstat (limited to 'src/com/android/launcher3/allapps')
4 files changed, 18 insertions, 321 deletions
diff --git a/src/com/android/launcher3/allapps/AllAppsCaretController.java b/src/com/android/launcher3/allapps/AllAppsCaretController.java index 622322bfc..583b49f7b 100644 --- a/src/com/android/launcher3/allapps/AllAppsCaretController.java +++ b/src/com/android/launcher3/allapps/AllAppsCaretController.java @@ -22,13 +22,14 @@ import android.view.animation.Interpolator; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.pageindicators.CaretDrawable; +import com.android.launcher3.touch.SwipeDetector; public class AllAppsCaretController { // Determines when the caret should flip. Should be accessed via getThreshold() private static final float CARET_THRESHOLD = 0.015f; private static final float CARET_THRESHOLD_LAND = 0.5f; // The velocity at which the caret will peak (i.e. exhibit a 90 degree bend) - private static final float PEAK_VELOCITY = VerticalPullDetector.RELEASE_VELOCITY_PX_MS * .7f; + private static final float PEAK_VELOCITY = SwipeDetector.RELEASE_VELOCITY_PX_MS * .7f; private Launcher mLauncher; diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index fb785fbb0..75dd76098 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -34,6 +34,7 @@ import com.android.launcher3.R; import com.android.launcher3.anim.SpringAnimationHandler; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.graphics.DrawableFactory; +import com.android.launcher3.touch.SwipeDetector; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import java.util.List; @@ -57,7 +58,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView { private SpringAnimationHandler mSpringAnimationHandler; private OverScrollHelper mOverScrollHelper; - private VerticalPullDetector mPullDetector; + private SwipeDetector mPullDetector; private float mContentTranslationY = 0; public static final Property<AllAppsRecyclerView, Float> CONTENT_TRANS_Y = @@ -94,9 +95,9 @@ public class AllAppsRecyclerView extends BaseRecyclerView { R.dimen.all_apps_empty_search_bg_top_offset); mOverScrollHelper = new OverScrollHelper(); - mPullDetector = new VerticalPullDetector(getContext()); + mPullDetector = new SwipeDetector(getContext()); mPullDetector.setListener(mOverScrollHelper); - mPullDetector.setDetectableScrollConditions(VerticalPullDetector.DIRECTION_BOTH, true); + mPullDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_BOTH, true); } public void setSpringAnimationHandler(SpringAnimationHandler springAnimationHandler) { @@ -479,7 +480,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView { y + mEmptySearchBackground.getIntrinsicHeight()); } - private class OverScrollHelper implements VerticalPullDetector.Listener { + private class OverScrollHelper implements SwipeDetector.Listener { private static final float MAX_RELEASE_VELOCITY = 5000; // px / s private static final float MAX_OVERSCROLL_PERCENTAGE = 0.07f; diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index 0859e0658..ecb972496 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -26,6 +26,7 @@ import com.android.launcher3.anim.SpringAnimationHandler; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.graphics.GradientView; import com.android.launcher3.graphics.ScrimView; +import com.android.launcher3.touch.SwipeDetector; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; import com.android.launcher3.util.SystemUiController; @@ -42,7 +43,7 @@ import com.android.launcher3.util.TouchController; * If release velocity < THRES1, snap according to either top or bottom depending on whether it's * closer to top or closer to the page indicator. */ -public class AllAppsTransitionController implements TouchController, VerticalPullDetector.Listener, +public class AllAppsTransitionController implements TouchController, SwipeDetector.Listener, SearchUiManager.OnScrollRangeChangeListener { private static final String TAG = "AllAppsTrans"; @@ -52,8 +53,8 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private final Interpolator mHotseatAccelInterpolator = new AccelerateInterpolator(1.5f); private final Interpolator mDecelInterpolator = new DecelerateInterpolator(3f); private final Interpolator mFastOutSlowInInterpolator = new FastOutSlowInInterpolator(); - private final VerticalPullDetector.ScrollInterpolator mScrollInterpolator - = new VerticalPullDetector.ScrollInterpolator(); + private final SwipeDetector.ScrollInterpolator mScrollInterpolator + = new SwipeDetector.ScrollInterpolator(); private static final float PARALLAX_COEFFICIENT = .125f; private static final int SINGLE_FRAME_MS = 16; @@ -69,7 +70,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul private float mStatusBarHeight; private final Launcher mLauncher; - private final VerticalPullDetector mDetector; + private final SwipeDetector mDetector; private final ArgbEvaluator mEvaluator; private final boolean mIsDarkTheme; @@ -106,7 +107,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul public AllAppsTransitionController(Launcher l) { mLauncher = l; - mDetector = new VerticalPullDetector(l); + mDetector = new SwipeDetector(l); mDetector.setListener(this); mShiftRange = DEFAULT_SHIFT_RANGE; mProgress = 1f; @@ -136,17 +137,17 @@ public class AllAppsTransitionController implements TouchController, VerticalPul if (mDetector.isIdleState()) { if (mLauncher.isAllAppsVisible()) { - directionsToDetectScroll |= VerticalPullDetector.DIRECTION_DOWN; + directionsToDetectScroll |= SwipeDetector.DIRECTION_DOWN; } else { - directionsToDetectScroll |= VerticalPullDetector.DIRECTION_UP; + directionsToDetectScroll |= SwipeDetector.DIRECTION_UP; } } else { if (isInDisallowRecatchBottomZone()) { - directionsToDetectScroll |= VerticalPullDetector.DIRECTION_UP; + directionsToDetectScroll |= SwipeDetector.DIRECTION_UP; } else if (isInDisallowRecatchTopZone()) { - directionsToDetectScroll |= VerticalPullDetector.DIRECTION_DOWN; + directionsToDetectScroll |= SwipeDetector.DIRECTION_DOWN; } else { - directionsToDetectScroll |= VerticalPullDetector.DIRECTION_BOTH; + directionsToDetectScroll |= SwipeDetector.DIRECTION_BOTH; ignoreSlopWhenSettling = true; } } diff --git a/src/com/android/launcher3/allapps/VerticalPullDetector.java b/src/com/android/launcher3/allapps/VerticalPullDetector.java deleted file mode 100644 index 13c4f63f0..000000000 --- a/src/com/android/launcher3/allapps/VerticalPullDetector.java +++ /dev/null @@ -1,306 +0,0 @@ -package com.android.launcher3.allapps; - -import android.content.Context; -import android.util.Log; -import android.view.MotionEvent; -import android.view.ViewConfiguration; -import android.view.animation.Interpolator; - -/** - * One dimensional scroll gesture detector for all apps container pull up interaction. - * Client (e.g., AllAppsTransitionController) of this class can register a listener. - * <p/> - * Features that this gesture detector can support. - */ -public class VerticalPullDetector { - - private static final boolean DBG = false; - private static final String TAG = "VerticalPullDetector"; - - private final float mTouchSlop; - - private int mScrollConditions; - public static final int DIRECTION_UP = 1 << 0; - public static final int DIRECTION_DOWN = 1 << 1; - public static final int DIRECTION_BOTH = DIRECTION_DOWN | DIRECTION_UP; - - private static final float ANIMATION_DURATION = 1200; - private static final float FAST_FLING_PX_MS = 10; - - /** - * The minimum release velocity in pixels per millisecond that triggers fling.. - */ - public static final float RELEASE_VELOCITY_PX_MS = 1.0f; - - /** - * The time constant used to calculate dampening in the low-pass filter of scroll velocity. - * Cutoff frequency is set at 10 Hz. - */ - public static final float SCROLL_VELOCITY_DAMPENING_RC = 1000f / (2f * (float) Math.PI * 10); - - /* Scroll state, this is set to true during dragging and animation. */ - private ScrollState mState = ScrollState.IDLE; - - enum ScrollState { - IDLE, - DRAGGING, // onDragStart, onDrag - SETTLING // onDragEnd - } - - //------------------- ScrollState transition diagram ----------------------------------- - // - // IDLE -> (mDisplacement > mTouchSlop) -> DRAGGING - // DRAGGING -> (MotionEvent#ACTION_UP, MotionEvent#ACTION_CANCEL) -> SETTLING - // SETTLING -> (MotionEvent#ACTION_DOWN) -> DRAGGING - // SETTLING -> (View settled) -> IDLE - - private void setState(ScrollState newState) { - if (DBG) { - Log.d(TAG, "setState:" + mState + "->" + newState); - } - // onDragStart and onDragEnd is reported ONLY on state transition - if (newState == ScrollState.DRAGGING) { - initializeDragging(); - if (mState == ScrollState.IDLE) { - reportDragStart(false /* recatch */); - } else if (mState == ScrollState.SETTLING) { - reportDragStart(true /* recatch */); - } - } - if (newState == ScrollState.SETTLING) { - reportDragEnd(); - } - - mState = newState; - } - - public boolean isDraggingOrSettling() { - return mState == ScrollState.DRAGGING || mState == ScrollState.SETTLING; - } - - /** - * There's no touch and there's no animation. - */ - public boolean isIdleState() { - return mState == ScrollState.IDLE; - } - - public boolean isSettlingState() { - return mState == ScrollState.SETTLING; - } - - public boolean isDraggingState() { - return mState == ScrollState.DRAGGING; - } - - private float mDownX; - private float mDownY; - - private float mLastY; - private long mCurrentMillis; - - private float mVelocity; - private float mLastDisplacement; - private float mDisplacementY; - private float mDisplacementX; - - private float mSubtractDisplacement; - private boolean mIgnoreSlopWhenSettling; - - /* Client of this gesture detector can register a callback. */ - private Listener mListener; - - public void setListener(Listener l) { - mListener = l; - } - - public interface Listener { - void onDragStart(boolean start); - - boolean onDrag(float displacement, float velocity); - - void onDragEnd(float velocity, boolean fling); - } - - public VerticalPullDetector(Context context) { - mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); - } - - public void setDetectableScrollConditions(int scrollDirectionFlags, boolean ignoreSlop) { - mScrollConditions = scrollDirectionFlags; - mIgnoreSlopWhenSettling = ignoreSlop; - } - - private boolean shouldScrollStart() { - // reject cases where the slop condition is not met. - if (Math.abs(mDisplacementY) < mTouchSlop) { - return false; - } - - // reject cases where the angle condition is not met. - float deltaY = Math.abs(mDisplacementY); - float deltaX = Math.max(Math.abs(mDisplacementX), 1); - if (deltaX > deltaY) { - return false; - } - // Check if the client is interested in scroll in current direction. - if (((mScrollConditions & DIRECTION_DOWN) > 0 && mDisplacementY > 0) || - ((mScrollConditions & DIRECTION_UP) > 0 && mDisplacementY < 0)) { - return true; - } - return false; - } - - public boolean onTouchEvent(MotionEvent ev) { - switch (ev.getAction()) { - case MotionEvent.ACTION_DOWN: - mDownX = ev.getX(); - mDownY = ev.getY(); - mLastDisplacement = 0; - mDisplacementY = 0; - mVelocity = 0; - - if (mState == ScrollState.SETTLING && mIgnoreSlopWhenSettling) { - setState(ScrollState.DRAGGING); - } - break; - case MotionEvent.ACTION_MOVE: - mDisplacementX = ev.getX() - mDownX; - mDisplacementY = ev.getY() - mDownY; - computeVelocity(ev); - - // handle state and listener calls. - if (mState != ScrollState.DRAGGING && shouldScrollStart()) { - setState(ScrollState.DRAGGING); - } - if (mState == ScrollState.DRAGGING) { - reportDragging(); - } - break; - case MotionEvent.ACTION_CANCEL: - case MotionEvent.ACTION_UP: - // These are synthetic events and there is no need to update internal values. - if (mState == ScrollState.DRAGGING) { - setState(ScrollState.SETTLING); - } - break; - default: - //TODO: add multi finger tracking by tracking active pointer. - break; - } - // Do house keeping. - mLastDisplacement = mDisplacementY; - mLastY = ev.getY(); - return true; - } - - public void finishedScrolling() { - setState(ScrollState.IDLE); - } - - private boolean reportDragStart(boolean recatch) { - mListener.onDragStart(!recatch); - if (DBG) { - Log.d(TAG, "onDragStart recatch:" + recatch); - } - return true; - } - - private void initializeDragging() { - if (mState == ScrollState.SETTLING && mIgnoreSlopWhenSettling) { - mSubtractDisplacement = 0; - } - if (mDisplacementY > 0) { - mSubtractDisplacement = mTouchSlop; - } else { - mSubtractDisplacement = -mTouchSlop; - } - } - - private boolean reportDragging() { - float delta = mDisplacementY - mLastDisplacement; - if (delta != 0) { - if (DBG) { - Log.d(TAG, String.format("onDrag disp=%.1f, velocity=%.1f", - mDisplacementY, mVelocity)); - } - - return mListener.onDrag(mDisplacementY - mSubtractDisplacement, mVelocity); - } - return true; - } - - private void reportDragEnd() { - if (DBG) { - Log.d(TAG, String.format("onScrollEnd disp=%.1f, velocity=%.1f", - mDisplacementY, mVelocity)); - } - mListener.onDragEnd(mVelocity, Math.abs(mVelocity) > RELEASE_VELOCITY_PX_MS); - - } - - /** - * Computes the damped velocity using the two motion events and the previous velocity. - */ - private float computeVelocity(MotionEvent to) { - return computeVelocity(to.getY() - mLastY, to.getEventTime()); - } - - public float computeVelocity(float delta, long currentMillis) { - long previousMillis = mCurrentMillis; - mCurrentMillis = currentMillis; - - float deltaTimeMillis = mCurrentMillis - previousMillis; - float velocity = (deltaTimeMillis > 0) ? (delta / deltaTimeMillis) : 0; - if (Math.abs(mVelocity) < 0.001f) { - mVelocity = velocity; - } else { - float alpha = computeDampeningFactor(deltaTimeMillis); - mVelocity = interpolate(mVelocity, velocity, alpha); - } - return mVelocity; - } - - /** - * Returns a time-dependent dampening factor using delta time. - */ - private static float computeDampeningFactor(float deltaTime) { - return deltaTime / (SCROLL_VELOCITY_DAMPENING_RC + deltaTime); - } - - /** - * Returns the linear interpolation between two values - */ - private static float interpolate(float from, float to, float alpha) { - return (1.0f - alpha) * from + alpha * to; - } - - public long calculateDuration(float velocity, float progressNeeded) { - // TODO: make these values constants after tuning. - float velocityDivisor = Math.max(2f, Math.abs(0.5f * velocity)); - float travelDistance = Math.max(0.2f, progressNeeded); - long duration = (long) Math.max(100, ANIMATION_DURATION / velocityDivisor * travelDistance); - if (DBG) { - Log.d(TAG, String.format("calculateDuration=%d, v=%f, d=%f", duration, velocity, progressNeeded)); - } - return duration; - } - - public static class ScrollInterpolator implements Interpolator { - - boolean mSteeper; - - public void setVelocityAtZero(float velocity) { - mSteeper = velocity > FAST_FLING_PX_MS; - } - - public float getInterpolation(float t) { - t -= 1.0f; - float output = t * t * t; - if (mSteeper) { - output *= t * t; // Make interpolation initial slope steeper - } - return output + 1; - } - } -} |