summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/util
diff options
context:
space:
mode:
authorJon Miranda <jonmiranda@google.com>2019-01-24 21:25:13 -0800
committerJon Miranda <jonmiranda@google.com>2019-01-24 21:25:32 -0800
commit71cb80cccb366cd960eeb0aef0ad9b21d9d34f9a (patch)
tree4842e39a4f4b24962367b06948471ee535d4ebba /src/com/android/launcher3/util
parent792fcc3aec4e085fc864541fb0396ef09bd23342 (diff)
downloadpackages_apps_Trebuchet-71cb80cccb366cd960eeb0aef0ad9b21d9d34f9a.tar.gz
packages_apps_Trebuchet-71cb80cccb366cd960eeb0aef0ad9b21d9d34f9a.tar.bz2
packages_apps_Trebuchet-71cb80cccb366cd960eeb0aef0ad9b21d9d34f9a.zip
Add springs when snapping between pages on the workspace.
- Behind feature flag QUICKSTEP_SPRINGS - Springs control settling the page and allow for overscroll for the first/last pages Bug: 111698021 Change-Id: Ib4a9ef59463cc46e31ac0766bf7705612f6c63c1
Diffstat (limited to 'src/com/android/launcher3/util')
-rw-r--r--src/com/android/launcher3/util/OverScroller.java77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/com/android/launcher3/util/OverScroller.java b/src/com/android/launcher3/util/OverScroller.java
index d697eceae..fc8a138ef 100644
--- a/src/com/android/launcher3/util/OverScroller.java
+++ b/src/com/android/launcher3/util/OverScroller.java
@@ -26,6 +26,11 @@ import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
+import androidx.dynamicanimation.animation.DynamicAnimation;
+import androidx.dynamicanimation.animation.FloatPropertyCompat;
+import androidx.dynamicanimation.animation.SpringAnimation;
+import androidx.dynamicanimation.animation.SpringForce;
+
/**
* Based on {@link android.widget.OverScroller} supporting only 1-d scrolling and with more
* customization options.
@@ -196,6 +201,9 @@ public class OverScroller {
switch (mMode) {
case SCROLL_MODE:
+ if (isSpringing()) {
+ return true;
+ }
long time = AnimationUtils.currentAnimationTimeMillis();
// Any scroller can be used for time, since they were started
// together in scroll mode. We use X here.
@@ -254,6 +262,22 @@ public class OverScroller {
}
/**
+ * Start scrolling using a spring by providing a starting point and the distance to travel.
+ *
+ * @param start Starting scroll offset in pixels. Positive
+ * numbers will scroll the content to the left.
+ * @param delta Distance to travel. Positive numbers will scroll the
+ * content to the left.
+ * @param duration Duration of the scroll in milliseconds.
+ * @param velocity The starting velocity for the spring in px per ms.
+ */
+ public void startScrollSpring(int start, int delta, int duration, float velocity) {
+ mMode = SCROLL_MODE;
+ mScroller.mState = mScroller.SPRING;
+ mScroller.startScroll(start, delta, duration, velocity);
+ }
+
+ /**
* Call this when you want to 'spring back' into a valid coordinate range.
*
* @param start Starting X coordinate
@@ -354,6 +378,10 @@ public class OverScroller {
return (int) (time - mScroller.mStartTime);
}
+ public boolean isSpringing() {
+ return mScroller.mState == SplineOverScroller.SPRING && !isFinished();
+ }
+
static class SplineOverScroller {
// Initial position
private int mStart;
@@ -397,6 +425,8 @@ public class OverScroller {
// Current state of the animation.
private int mState = SPLINE;
+ private SpringAnimation mSpring;
+
// Constant gravity value, used in the deceleration phase.
private static final float GRAVITY = 2000.0f;
@@ -417,6 +447,20 @@ public class OverScroller {
private static final int SPLINE = 0;
private static final int CUBIC = 1;
private static final int BALLISTIC = 2;
+ private static final int SPRING = 3;
+
+ private static final FloatPropertyCompat<SplineOverScroller> SPRING_PROPERTY =
+ new FloatPropertyCompat<SplineOverScroller>("splineOverScrollerSpring") {
+ @Override
+ public float getValue(SplineOverScroller scroller) {
+ return scroller.mCurrentPosition;
+ }
+
+ @Override
+ public void setValue(SplineOverScroller scroller, float value) {
+ scroller.mCurrentPosition = (int) value;
+ }
+ };
static {
float x_min = 0.0f;
@@ -465,6 +509,9 @@ public class OverScroller {
}
void updateScroll(float q) {
+ if (mState == SPRING) {
+ return;
+ }
mCurrentPosition = mStart + Math.round(q * (mFinal - mStart));
}
@@ -495,6 +542,10 @@ public class OverScroller {
}
void startScroll(int start, int distance, int duration) {
+ startScroll(start, distance, duration, 0);
+ }
+
+ void startScroll(int start, int distance, int duration, float velocity) {
mFinished = false;
mCurrentPosition = mStart = start;
@@ -503,12 +554,31 @@ public class OverScroller {
mStartTime = AnimationUtils.currentAnimationTimeMillis();
mDuration = duration;
+ if (mState == SPRING) {
+ if (mSpring != null) {
+ mSpring.cancel();
+ }
+ mSpring = new SpringAnimation(this, SPRING_PROPERTY);
+
+ mSpring.setSpring(new SpringForce(mFinal)
+ .setStiffness(SpringForce.STIFFNESS_LOW)
+ .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY));
+ mSpring.setStartVelocity(velocity);
+ mSpring.animateToFinalPosition(mFinal);
+ mSpring.addEndListener((animation, canceled, value, velocity1) -> {
+ finish();
+ mState = SPLINE;
+ mSpring = null;
+ });
+ }
// Unused
mDeceleration = 0.0f;
mVelocity = 0;
}
void finish() {
+ if (mSpring != null && mSpring.isRunning()) mSpring.cancel();
+
mCurrentPosition = mFinal;
// Not reset since WebView relies on this value for fast fling.
// TODO: restore when WebView uses the fast fling implemented in this class.
@@ -518,6 +588,9 @@ public class OverScroller {
void setFinalPosition(int position) {
mFinal = position;
+ if (mState == SPRING && mSpring != null) {
+ mSpring.animateToFinalPosition(mFinal);
+ }
mSplineDistance = mFinal - mStart;
mFinished = false;
}
@@ -722,6 +795,10 @@ public class OverScroller {
* reached.
*/
boolean update() {
+ if (mState == SPRING) {
+ return mFinished;
+ }
+
final long time = AnimationUtils.currentAnimationTimeMillis();
final long currentTime = time - mStartTime;