diff options
author | Jon Miranda <jonmiranda@google.com> | 2019-01-24 21:25:13 -0800 |
---|---|---|
committer | Jon Miranda <jonmiranda@google.com> | 2019-01-24 21:25:32 -0800 |
commit | 71cb80cccb366cd960eeb0aef0ad9b21d9d34f9a (patch) | |
tree | 4842e39a4f4b24962367b06948471ee535d4ebba /src/com/android/launcher3/util | |
parent | 792fcc3aec4e085fc864541fb0396ef09bd23342 (diff) | |
download | packages_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.java | 77 |
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; |