Polish for all apps physics.

By adjusting the start value based on the direction of the scroll,
the springs will appear more smooth.

This only changes the appearance of the spring when scrolling down,
since the start value has always been 1 and thus looked fine when
scrolling up.

Bug: 38349031
Change-Id: I563e6e7cfdbc74c4a95adb22f90d5efe17dfa453
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 189b935..499eb45 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -423,8 +423,9 @@
 
             // We only show the spring animation when at the top or bottom, so we wait until the
             // first or last row is visible to ensure that all animations run in sync.
-            if ((first == 0 && dy < 0) || (last == mAdapter.getItemCount() - 1 && dy > 0)) {
-                mSpringAnimationHandler.animateToFinalPosition(0);
+            boolean scrollUp = dy < 0;
+            if ((first == 0 && scrollUp) || (last == mAdapter.getItemCount() - 1 && dy > 0)) {
+                mSpringAnimationHandler.animateToFinalPosition(0, scrollUp ? 1 : -1);
             }
         }
 
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index a2bd43d..34421bd 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -511,7 +511,9 @@
                 if (FeatureFlags.LAUNCHER3_PHYSICS) {
                     // We calculate our own velocity to give the springs the desired effect.
                     velocity = y / getDampedOverScroll(getHeight()) * MAX_RELEASE_VELOCITY;
-                    mSpringAnimationHandler.animateToPositionWithVelocity(0, -velocity);
+                    // We want to negate the velocity because we are moving to 0 from -1 due to the
+                    // downward motion. (y-axis -1 is above 0).
+                    mSpringAnimationHandler.animateToPositionWithVelocity(0, -1, -velocity);
                 }
 
                 ObjectAnimator.ofFloat(AllAppsRecyclerView.this,
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 4d112c6..0859e06 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -228,7 +228,8 @@
                 }
                 mLauncher.showAppsView(true /* animated */, false /* updatePredictedApps */);
                 if (hasSpringAnimationHandler()) {
-                    mSpringAnimationHandler.animateToFinalPosition(0);
+                    // The icons are moving upwards, so we go to 0 from 1. (y-axis 1 is below 0.)
+                    mSpringAnimationHandler.animateToFinalPosition(0 /* pos */, 1 /* startValue */);
                 }
             } else {
                 calculateDuration(velocity, Math.abs(mShiftRange - mAppsView.getTranslationY()));
diff --git a/src/com/android/launcher3/anim/SpringAnimationHandler.java b/src/com/android/launcher3/anim/SpringAnimationHandler.java
index 1efc4e4..3e58adc 100644
--- a/src/com/android/launcher3/anim/SpringAnimationHandler.java
+++ b/src/com/android/launcher3/anim/SpringAnimationHandler.java
@@ -111,16 +111,32 @@
         mShouldComputeVelocity = true;
     }
 
-    public void animateToFinalPosition(float position) {
-        if (DEBUG) Log.d(TAG, "animateToFinalPosition#computeVelocity=" + mShouldComputeVelocity);
+    public void animateToFinalPosition(float position, int startValue) {
+        animateToFinalPosition(position, startValue, mShouldComputeVelocity);
+    }
+
+    /**
+     * @param position The final animation position.
+     * @param startValue < 0 if scrolling from start to end; > 0 if scrolling from end to start
+     *                   The magnitude of the number changes how the spring will move.
+     * @param setVelocity If true, we set the velocity to {@link #mCurrentVelocity} before
+     *                    starting the animation.
+     */
+    private void animateToFinalPosition(float position, int startValue, boolean setVelocity) {
+        if (DEBUG) {
+            Log.d(TAG, "animateToFinalPosition#position=" + position + ", startValue=" + startValue);
+        }
 
         if (mShouldComputeVelocity) {
-            computeVelocity();
-            setStartVelocity(mCurrentVelocity);
+            mCurrentVelocity = computeVelocity();
         }
 
         int size = mAnimations.size();
         for (int i = 0; i < size; ++i) {
+            mAnimations.get(i).setStartValue(startValue);
+            if (setVelocity) {
+                mAnimations.get(i).setStartVelocity(mCurrentVelocity);
+            }
             mAnimations.get(i).animateToFinalPosition(position);
         }
 
@@ -128,15 +144,18 @@
     }
 
     /**
-     * Similar to {@link #animateToFinalPosition(float)}, but used in cases where we want to
+     * Similar to {@link #animateToFinalPosition(float, int)}, but used in cases where we want to
      * manually set the velocity.
      */
-    public void animateToPositionWithVelocity(float position, float velocity) {
-        if (DEBUG) Log.d(TAG, "animateToPosition#velocity=" + velocity);
+    public void animateToPositionWithVelocity(float position, int startValue, float velocity) {
+        if (DEBUG) {
+            Log.d(TAG, "animateToPosition#pos=" + position + ", start=" + startValue
+                    + ", velocity=" + velocity);
+        }
 
-        setStartVelocity(velocity);
+        mCurrentVelocity = velocity;
         mShouldComputeVelocity = false;
-        animateToFinalPosition(position);
+        animateToFinalPosition(position, startValue, true);
     }
 
 
@@ -163,27 +182,20 @@
             mVelocityTracker = null;
         }
         mCurrentVelocity = 0;
+        mShouldComputeVelocity = false;
     }
 
-    private void setStartVelocity(float velocity) {
-        if (DEBUG) Log.d(TAG, "setStartVelocity=" + velocity);
 
-        int size = mAnimations.size();
-        for (int i = 0; i < size; ++i) {
-            mAnimations.get(i).setStartVelocity(velocity);
-        }
-    }
-
-    private void computeVelocity() {
+    private float computeVelocity() {
         getVelocityTracker().computeCurrentVelocity(1000 /* millis */);
 
-        mCurrentVelocity = isVerticalDirection()
+        float velocity = isVerticalDirection()
                 ? getVelocityTracker().getYVelocity()
                 : getVelocityTracker().getXVelocity();
-        mCurrentVelocity *= VELOCITY_DAMPING_FACTOR;
-        mShouldComputeVelocity = false;
+        velocity *= VELOCITY_DAMPING_FACTOR;
 
-        if (DEBUG) Log.d(TAG, "computeVelocity=" + mCurrentVelocity);
+        if (DEBUG) Log.d(TAG, "computeVelocity=" + velocity);
+        return velocity;
     }
 
     private boolean isVerticalDirection() {
@@ -221,7 +233,6 @@
      */
     public static SpringAnimation forView(View view, FloatPropertyCompat property, float finalPos) {
         SpringAnimation spring = new SpringAnimation(view, property, finalPos);
-        spring.setStartValue(1f);
         spring.setSpring(new SpringForce(finalPos));
         return spring;
     }