summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/allapps
diff options
context:
space:
mode:
authorHyunyoung Song <hyunyoungs@google.com>2017-07-06 12:35:55 -0700
committerHyunyoung Song <hyunyoungs@google.com>2017-07-06 14:32:35 -0700
commitf40e94955cba0ca351f587358b9e07496d132a1b (patch)
treeada5929c818f0fb9db689af4154bd144d7c39ab6 /src/com/android/launcher3/allapps
parent19b3165c890ecb897a2c3f519db78aba1b5d64df (diff)
downloadandroid_packages_apps_Trebuchet-f40e94955cba0ca351f587358b9e07496d132a1b.tar.gz
android_packages_apps_Trebuchet-f40e94955cba0ca351f587358b9e07496d132a1b.tar.bz2
android_packages_apps_Trebuchet-f40e94955cba0ca351f587358b9e07496d132a1b.zip
Add tests to SwipeDetector (formerly VerticalPullDetector).
Change-Id: I09ab4f22d7204ad806825ab0d6374c2b9616bf39
Diffstat (limited to 'src/com/android/launcher3/allapps')
-rw-r--r--src/com/android/launcher3/allapps/AllAppsCaretController.java3
-rw-r--r--src/com/android/launcher3/allapps/AllAppsRecyclerView.java9
-rw-r--r--src/com/android/launcher3/allapps/AllAppsTransitionController.java21
-rw-r--r--src/com/android/launcher3/allapps/VerticalPullDetector.java306
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;
- }
- }
-}