Polishing home transitions

-Modified interpolation / duration and some other characteristics
 of the transitions between home and AllApps / Customize

Change-Id: I9154800d500b394e4f826f6c88c14fb6e0164828
diff --git a/res/values-xlarge/config.xml b/res/values-xlarge/config.xml
index 9c01e3c..fa7af5e 100644
--- a/res/values-xlarge/config.xml
+++ b/res/values-xlarge/config.xml
@@ -1,9 +1,9 @@
 <resources>
     <!--  NOTE: Many of the all apps values here are also used for the customization drawer -->
 
-    <!-- Duration in milliseconds of the all apps zoom-in animation. -->
+    <!-- Duration in milliseconds of the all apps / configuration zoom-in animation. -->
     <!-- NB: This should be less than the workspaceShrinkTime as they happen together. -->
-    <integer name="config_allAppsZoomInTime">350</integer>
+    <integer name="config_allAppsZoomInTime">700</integer>
 
     <!-- Duration in milliseconds of the transition between tabs in the all apps/customize
          tray -->
@@ -14,16 +14,14 @@
     <integer name="config_allAppsZoomOutTime">350</integer>
 
     <!-- Scaling factor used in the all apps zooming animations -->
-    <integer name="config_allAppsZoomScaleFactor">5</integer>
-
-    <!-- The extra distance off-screen that all apps appears from -->
-    <integer name="config_allAppsVerticalOffset">200</integer>
+    <integer name="config_allAppsZoomScaleFactor">7</integer>
 
     <!-- Duration in milliseconds of the animations between all apps, customize, & home.
          NOTE: If these are changed, the toolbar animation times below should also be. -->
     <integer name="config_allAppsCameraPanTime">700</integer>
     <integer name="config_workspaceShrinkTime">700</integer>
-    <integer name="config_workspaceUnshrinkTime">700</integer>
+    <integer name="config_workspaceUnshrinkTime">350</integer>
+    <integer name="config_allAppsFadeOutTime">150</integer>
 
     <!-- Duration in milliseconds toolbar fade in and fade out animations.
          NOTE: Fade in and fade out time should together be less the transition
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 37c2b41..464ea64 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -2515,14 +2515,16 @@
      */
     private void setPivotsForZoom(View view, State state, float scaleFactor) {
         final int height = view.getHeight();
+
         view.setPivotX(view.getWidth() / 2.0f);
-        // Set pivotY so that at the starting zoom factor, the view is off-screen by a small margin
-        // Assumes that the view is normally anchored to either the top or bottom of the screen
-        final int margin = getResources().getInteger(R.integer.config_allAppsVerticalOffset);
+        // Set pivotY so that at the starting zoom factor, the view is partially
+        // visible. Modifying initialHeightFactor changes how much of the view is
+        // initially showing, and hence the perceived angle from which the view enters.
+        final float initialHeightFactor = 0.2f;
         if (state == State.ALL_APPS) {
-            view.setPivotY(height + ((view.getTop() + height) / scaleFactor) + margin);
+            view.setPivotY((1 + initialHeightFactor) * height);
         } else {
-            view.setPivotY(0.0f - (view.getTop() / scaleFactor) - margin);
+            view.setPivotY(-initialHeightFactor * height);
         }
     }
 
@@ -2552,7 +2554,8 @@
                     PropertyValuesHolder.ofFloat("scaleX", scale, 1.0f),
                     PropertyValuesHolder.ofFloat("scaleY", scale, 1.0f));
             scaleAnim.setDuration(duration);
-            scaleAnim.setInterpolator(new DecelerateInterpolator());
+
+            scaleAnim.setInterpolator(new Workspace.ZoomOutInterpolator());
             scaleAnim.addListener(new LauncherAnimatorListenerAdapter() {
                 @Override
                 public void onAnimationStart(Animator animation) {
@@ -2560,6 +2563,7 @@
                     toView.setTranslationX(0.0f);
                     toView.setTranslationY(0.0f);
                     toView.setVisibility(View.VISIBLE);
+                    toView.setAlpha(1.0f);
                 }
                 @Override
                 public void onAnimationEndOrCancel(Animator animation) {
@@ -2624,8 +2628,12 @@
                     PropertyValuesHolder.ofFloat("scaleX", scaleFactor),
                     PropertyValuesHolder.ofFloat("scaleY", scaleFactor));
             scaleAnim.setDuration(duration);
-            scaleAnim.setInterpolator(new AccelerateInterpolator());
-            mStateAnimation.addListener(new LauncherAnimatorListenerAdapter() {
+            scaleAnim.setInterpolator(new Workspace.ZoomInInterpolator());
+
+            ValueAnimator alphaAnim = ObjectAnimator.ofPropertyValuesHolder(fromView,
+                    PropertyValuesHolder.ofFloat("alpha", 1.0f, 0.0f));
+            alphaAnim.setDuration(res.getInteger(R.integer.config_allAppsFadeOutTime));
+            alphaAnim.addListener(new LauncherAnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEndOrCancel(Animator animation) {
                     fromView.setVisibility(View.GONE);
@@ -2636,7 +2644,7 @@
             AnimatorSet toolbarShowAnim = new AnimatorSet();
             hideAndShowToolbarButtons(State.WORKSPACE, toolbarShowAnim, toolbarHideAnim);
 
-            mStateAnimation.playTogether(scaleAnim, toolbarHideAnim);
+            mStateAnimation.playTogether(scaleAnim, toolbarHideAnim, alphaAnim);
 
             // Show the new toolbar buttons at the very end of the whole animation
             final int fadeInTime = res.getInteger(R.integer.config_toolbarButtonFadeInTime);
@@ -2688,6 +2696,7 @@
                 public void onAnimationStart(Animator animation) {
                     toView.setVisibility(View.VISIBLE);
                     toView.setY(toViewStartY);
+                    toView.setAlpha(1.0f);
                 }
                 @Override
                 public void onAnimationEndOrCancel(Animator animation) {
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 82fd362..7e33a2c 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -847,11 +847,6 @@
 
             if (animated) {
                 final int duration = res.getInteger(R.integer.config_workspaceShrinkTime);
-                ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(cl,
-                        PropertyValuesHolder.ofFloat("backgroundAlpha", finalAlpha),
-                        PropertyValuesHolder.ofFloat("alpha", finalAlpha),
-                        PropertyValuesHolder.ofFloat("rotationY", rotation));
-                anim.setDuration(duration);
 
                 ObjectAnimator animWithInterpolator = ObjectAnimator.ofPropertyValuesHolder(cl,
                         PropertyValuesHolder.ofFloat("x", newX),
@@ -859,10 +854,14 @@
                         PropertyValuesHolder.ofFloat("scaleX",
                                 SHRINK_FACTOR * rotationScaleX * extraShrinkFactor),
                         PropertyValuesHolder.ofFloat("scaleY",
-                                SHRINK_FACTOR * rotationScaleY * extraShrinkFactor));
+                                SHRINK_FACTOR * rotationScaleY * extraShrinkFactor),
+                        PropertyValuesHolder.ofFloat("backgroundAlpha", finalAlpha),
+                        PropertyValuesHolder.ofFloat("alpha", finalAlpha),
+                        PropertyValuesHolder.ofFloat("rotationY", rotation));
+
                 animWithInterpolator.setDuration(duration);
-                animWithInterpolator.setInterpolator(mZInterpolator);
-                mAnimator.playTogether(anim, animWithInterpolator);
+                animWithInterpolator.setInterpolator(mZoomOutInterpolator);
+                mAnimator.playTogether(animWithInterpolator);
             } else {
                 cl.setX((int)newX);
                 cl.setY((int)newY);
@@ -881,22 +880,64 @@
         setChildrenDrawnWithCacheEnabled(true);
     }
 
-    private class ZInterpolator implements TimeInterpolator {
-        private final float focalLength = 0.2f;
+    /*
+     * This interpolator emulates the rate at which the perceived scale of an object changes
+     * as its distance from a camera increases. When this interpolator is applied to a scale
+     * animation on a view, it evokes the sense that the object is shrinking due to moving away
+     * from the camera. 
+     */
+    static class ZInterpolator implements TimeInterpolator {
+        private float focalLength;
+
+        public ZInterpolator(float foc) {
+            focalLength = foc;
+        }
+
         public float getInterpolation(float input) {
             return (1.0f - focalLength / (focalLength + input)) /
-                    (1.0f - focalLength / (focalLength + 1.0f));
+                (1.0f - focalLength / (focalLength + 1.0f));
         }
     }
 
-    private class InverseZInterpolator implements TimeInterpolator {
+    /*
+     * The exact reverse of ZInterpolator.
+     */
+    static class InverseZInterpolator implements TimeInterpolator {
+        private ZInterpolator zInterpolator;
+        public InverseZInterpolator(float foc) {
+            zInterpolator = new ZInterpolator(foc);
+        }
         public float getInterpolation(float input) {
-            return 1 - mZInterpolator.getInterpolation(1 - input);
+            return 1 - zInterpolator.getInterpolation(1 - input);
         }
     }
 
-    private final ZInterpolator mZInterpolator = new ZInterpolator();
-    private final InverseZInterpolator mInverseZInterpolator = new InverseZInterpolator();
+    /*
+     * ZInterpolator compounded with an ease-out.
+     */
+    static class ZoomOutInterpolator implements TimeInterpolator {
+        private final ZInterpolator zInterpolator = new ZInterpolator(0.2f);
+        private final DecelerateInterpolator decelerate = new DecelerateInterpolator(1.5f);
+
+        public float getInterpolation(float input) {
+            return decelerate.getInterpolation(zInterpolator.getInterpolation(input));
+        }
+    }
+
+    /*
+     * InvereZInterpolator compounded with an ease-out.
+     */
+    static class ZoomInInterpolator implements TimeInterpolator {
+        private final InverseZInterpolator inverseZInterpolator = new InverseZInterpolator(0.35f);
+        private final DecelerateInterpolator decelerate = new DecelerateInterpolator(3.0f);
+
+        public float getInterpolation(float input) {
+            return decelerate.getInterpolation(inverseZInterpolator.getInterpolation(input));
+        }
+    }
+
+    private final ZoomOutInterpolator mZoomOutInterpolator = new ZoomOutInterpolator();
+    private final ZoomInInterpolator mZoomInInterpolator = new ZoomInInterpolator();
 
     private void updateWhichPagesAcceptDrops(ShrinkPosition state) {
         updateWhichPagesAcceptDropsHelper(state, false, 1, 1);
@@ -1026,20 +1067,18 @@
                 }
 
                 if (animated) {
-                    ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(cl,
-                            PropertyValuesHolder.ofFloat("backgroundAlpha", 0.0f),
-                            PropertyValuesHolder.ofFloat("alpha", finalAlphaValue),
-                            PropertyValuesHolder.ofFloat("rotationY", rotation));
-                    anim.setDuration(duration);
 
                     ObjectAnimator animWithInterpolator = ObjectAnimator.ofPropertyValuesHolder(cl,
                             PropertyValuesHolder.ofFloat("translationX", 0.0f),
                             PropertyValuesHolder.ofFloat("translationY", 0.0f),
                             PropertyValuesHolder.ofFloat("scaleX", 1.0f),
-                            PropertyValuesHolder.ofFloat("scaleY", 1.0f));
+                            PropertyValuesHolder.ofFloat("scaleY", 1.0f),
+                            PropertyValuesHolder.ofFloat("backgroundAlpha", 0.0f),
+                            PropertyValuesHolder.ofFloat("alpha", finalAlphaValue),
+                            PropertyValuesHolder.ofFloat("rotationY", rotation));
                     animWithInterpolator.setDuration(duration);
-                    animWithInterpolator.setInterpolator(mInverseZInterpolator);
-                    mAnimator.playTogether(anim, animWithInterpolator);
+                    animWithInterpolator.setInterpolator(mZoomInInterpolator);
+                    mAnimator.playTogether(animWithInterpolator);
                 } else {
                     cl.setTranslationX(0.0f);
                     cl.setTranslationY(0.0f);