Move all apps to the new animation framework, and some other all apps changes

Change-Id: Ib4c827966423d76e62db24036bbca0cd6ee46b95
diff --git a/res/layout-xlarge/all_apps_tabbed.xml b/res/layout-xlarge/all_apps_tabbed.xml
index a5f3d6f..c772706 100644
--- a/res/layout-xlarge/all_apps_tabbed.xml
+++ b/res/layout-xlarge/all_apps_tabbed.xml
@@ -38,7 +38,7 @@
                     android:drawSelectorOnTop="false"
                     android:listSelector="@drawable/grid_selector"
                     android:verticalSpacing="10dip"
-                    android:numColumns="4"
+                    android:numColumns="8"
                     android:fadingEdgeLength="0dip"
                     android:cacheColorHint="#00000000"
                     android:layout_width="match_parent"
diff --git a/res/values-xlarge/config.xml b/res/values-xlarge/config.xml
new file mode 100644
index 0000000..2f94c40
--- /dev/null
+++ b/res/values-xlarge/config.xml
@@ -0,0 +1,18 @@
+<resources>
+    <!-- Duration in milliseconds of the all apps zoom-in animation. -->
+    <!-- NB: This should be less than the workspaceShrinkTime as they happen together. -->
+    <integer name="config_allAppsZoomInTime">350</integer>
+
+    <!-- Duration in milliseconds of the all apps zoom-out animation -->
+    <!-- NB: This should be less than the workspaceUnshrinkTime as they happen together. -->
+    <integer name="config_allAppsZoomOutTime">350</integer>
+
+    <!-- Scaling factor used in the all apps zooming animations -->
+    <integer name="config_allAppsZoomScaleFactor">5</integer>
+
+    <!-- Duration in milliseconds of the workspace shrink animation -->
+    <integer name="config_workspaceShrinkTime">700</integer>
+
+    <!-- Duration in milliseconds of the workspace unshrink animation -->
+    <integer name="config_workspaceUnshrinkTime">700</integer>
+</resources>
\ No newline at end of file
diff --git a/src/com/android/launcher2/AllAppsTabbed.java b/src/com/android/launcher2/AllAppsTabbed.java
index 2002703..3aa70f4 100644
--- a/src/com/android/launcher2/AllAppsTabbed.java
+++ b/src/com/android/launcher2/AllAppsTabbed.java
@@ -92,7 +92,10 @@
         });
 
         setCurrentTab(0);
-        setVisibility(GONE);
+
+        // It needs to be INVISIBLE so that it will be measured in the layout.
+        // Otherwise the animations is messed up when we show it for the first time.
+        setVisibility(INVISIBLE);
     }
 
     @Override
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index ee85436..8557241 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -19,6 +19,11 @@
 import com.android.common.Search;
 import com.android.launcher.R;
 
+import android.animation.Animatable;
+import android.animation.AnimatableListenerAdapter;
+import android.animation.Animator;
+import android.animation.PropertyAnimator;
+import android.animation.Sequencer;
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -34,8 +39,8 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.Intent.ShortcutIconResource;
+import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
@@ -68,12 +73,13 @@
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.View.OnLongClickListener;
 import android.view.ViewGroup;
 import android.view.WindowManager;
-import android.view.View.OnLongClickListener;
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
-import android.view.animation.Animation.AnimationListener;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.EditText;
 import android.widget.ImageView;
@@ -2062,10 +2068,42 @@
             mWorkspace.shrinkToBottom(animated);
         }
         if (LauncherApplication.isScreenXLarge() && animated) {
-            // Not really a zoom -- this just makes the view visible
-            mAllAppsGrid.zoom(1.0f, false);
-            Animation anim = AnimationUtils.loadAnimation(this, R.anim.all_apps_zoom_in);
-            ((View) mAllAppsGrid).startAnimation(anim);
+            final View allApps = (View)mAllAppsGrid;
+
+            final Resources res = getResources();
+            final int duration = res.getInteger(R.integer.config_allAppsZoomInTime);
+            final float scale = (float) res.getInteger(R.integer.config_allAppsZoomScaleFactor);
+            final int height = allApps.getHeight();
+
+            // All apps should appear right at the end of the workspace shrink animation
+            final int startDelay = res.getInteger(R.integer.config_workspaceShrinkTime) - duration;
+
+            Interpolator interp = new DecelerateInterpolator(2.0f);
+
+            allApps.setPivotX(allApps.getWidth() / 2.0f);
+            allApps.setPivotY(height);
+
+            Animator scaleXAnim = new PropertyAnimator(duration, allApps, "scaleX", scale, 1.0f);
+            scaleXAnim.setInterpolator(interp);
+            scaleXAnim.addListener(new AnimatableListenerAdapter() {
+                public void onAnimationStart(Animatable animation) {
+                    // Not really a zoom -- this just makes the view visible
+                    mAllAppsGrid.zoom(1.0f, false);
+                }
+            });
+
+            Animator scaleYAnim = new PropertyAnimator(duration, allApps, "scaleY", scale, 1.0f);
+            scaleYAnim.setInterpolator(interp);
+
+            // Translate down by 20% of the total height
+            float oldY = (-allApps.getHeight() * 0.2f);
+            Animator yAnim = new PropertyAnimator(duration, allApps, "y", oldY, 0.0f);
+            yAnim.setInterpolator(interp);
+
+            Sequencer s = new Sequencer();
+            s.playTogether(scaleXAnim, scaleYAnim, yAnim);
+            s.play(scaleXAnim).after(startDelay);
+            s.start();
         } else {
             mAllAppsGrid.zoom(1.0f, animated);
         }
@@ -2120,15 +2158,29 @@
         if (mAllAppsGrid.isVisible()) {
             mWorkspace.setVisibility(View.VISIBLE);
             if (LauncherApplication.isScreenXLarge() && animated) {
-                Animation anim = AnimationUtils.loadAnimation(this, R.anim.all_apps_zoom_out);
-                anim.setAnimationListener(new AnimationListener() {
-                    public void onAnimationStart(Animation animation) {}
-                    public void onAnimationRepeat(Animation animation) {}
-                    public void onAnimationEnd(Animation animation) {
+                Resources res = getResources();
+                int duration = res.getInteger(R.integer.config_allAppsZoomOutTime);
+                float scaleFactor = (float) res.getInteger(R.integer.config_allAppsZoomScaleFactor);
+                View allApps = (View) mAllAppsGrid;
+
+                allApps.setPivotX(allApps.getWidth() / 2.0f);
+                allApps.setPivotY(allApps.getHeight());
+
+                // Translate up by 20% of the total height
+                float newY = allApps.getY() - allApps.getHeight() * 0.2f;
+
+                Sequencer seq = new Sequencer();
+                seq.playTogether(
+                        new PropertyAnimator(duration, allApps, "scaleX", scaleFactor),
+                        new PropertyAnimator(duration, allApps, "scaleY", scaleFactor),
+                        new PropertyAnimator(duration, allApps, "y", newY));
+                seq.addListener(new AnimatableListenerAdapter() {
+                    public void onAnimationEnd(Animatable animation) {
                         mAllAppsGrid.zoom(0.0f, false);
                     }
                 });
-                ((View)mAllAppsGrid).startAnimation(anim);
+                // Start the AllApps animation at the same time as the workspace unshrink
+                seq.start();
                 mWorkspace.unshrink();
             } else {
                 mAllAppsGrid.zoom(0.0f, animated);
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 15b12b7..35a767d 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -17,12 +17,13 @@
 package com.android.launcher2;
 
 import com.android.launcher.R;
-import com.android.launcher2.CellLayout.LayoutParams;
 
 import android.animation.Animatable;
+import android.animation.Animatable.AnimatableListener;
+import android.animation.Animator;
+import android.animation.Animator.AnimatorUpdateListener;
 import android.animation.PropertyAnimator;
 import android.animation.Sequencer;
-import android.animation.Animatable.AnimatableListener;
 import android.app.WallpaperManager;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
@@ -31,6 +32,7 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
+import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Paint;
@@ -46,14 +48,12 @@
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
-import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
+import android.view.animation.Animation.AnimationListener;
 import android.view.animation.Interpolator;
 import android.view.animation.RotateAnimation;
-import android.view.animation.Animation.AnimationListener;
 import android.widget.Scroller;
 import android.widget.TextView;
 import android.widget.Toast;
@@ -1087,11 +1087,12 @@
     // we use this to shrink the workspace for the all apps view and the customize view
     private void shrink(boolean shrinkToTop, boolean animated) {
         mIsSmall = true;
+        final Resources res = getResources();
         final int screenWidth = getWidth();
         final int screenHeight = getHeight();
-        final int scaledScreenWidth = (int)(SHRINK_FACTOR*screenWidth);
-        final int scaledScreenHeight = (int)(SHRINK_FACTOR*screenHeight);
-        final float scaledSpacing = getResources().getDimension(R.dimen.smallScreenSpacing);
+        final int scaledScreenWidth = (int) (SHRINK_FACTOR * screenWidth);
+        final int scaledScreenHeight = (int) (SHRINK_FACTOR * screenHeight);
+        final float scaledSpacing = res.getDimension(R.dimen.smallScreenSpacing);
 
         final int screenCount = getChildCount();
         float totalWidth = screenCount * scaledScreenWidth + (screenCount - 1) * scaledSpacing;
@@ -1110,21 +1111,13 @@
         for (int i = 0; i < screenCount; i++) {
             CellLayout cl = (CellLayout) getChildAt(i);
             if (animated) {
-                PropertyAnimator translateX = new PropertyAnimator(
-                        500, cl, "x", cl.getX(), (int) newX);
-                PropertyAnimator translateY = new PropertyAnimator(
-                        500, cl, "y", cl.getY(), (int) newY);
-                PropertyAnimator scaleX = new PropertyAnimator(
-                        500, cl, "scaleX", cl.getScaleX(), SHRINK_FACTOR);
-                PropertyAnimator scaleY = new PropertyAnimator(
-                        500, cl, "scaleY", cl.getScaleY(), SHRINK_FACTOR);
-                PropertyAnimator alpha = new PropertyAnimator(
-                        500, cl, "dimmedBitmapAlpha", cl.getDimmedBitmapAlpha(), 1.0f);
-                Sequencer.Builder b = s.play(translateX);
-                b.with(translateY);
-                b.with(scaleX);
-                b.with(scaleY);
-                b.with(alpha);
+                final int duration = res.getInteger(R.integer.config_workspaceShrinkTime);
+                s.playTogether(
+                        new PropertyAnimator(duration, cl, "x", newX),
+                        new PropertyAnimator(duration, cl, "y", newY),
+                        new PropertyAnimator(duration, cl, "scaleX", SHRINK_FACTOR),
+                        new PropertyAnimator(duration, cl, "scaleY", SHRINK_FACTOR),
+                        new PropertyAnimator(duration, cl, "dimmedBitmapAlpha", 1.0f));
             } else {
                 cl.setX((int)newX);
                 cl.setY((int)newY);
@@ -1137,7 +1130,7 @@
             cl.setOnInterceptTouchListener(this);
         }
         setChildrenDrawnWithCacheEnabled(true);
-        s.start();
+        if (animated) s.start();
     }
 
     // We call this when we trigger an unshrink by clicking on the CellLayout cl
@@ -1168,20 +1161,15 @@
             Sequencer s = new Sequencer();
             final int screenCount = getChildCount();
             for (int i = 0; i < screenCount; i++) {
-                CellLayout cl = (CellLayout)getChildAt(i);
-                int x = screenWidth * i;
-
-                PropertyAnimator translateX = new PropertyAnimator(500, cl, "x", cl.getX(), x);
-                PropertyAnimator translateY = new PropertyAnimator(500, cl, "y", cl.getY(), 0);
-                PropertyAnimator scaleX = new PropertyAnimator(500, cl, "scaleX", cl.getScaleX(), 1.0f);
-                PropertyAnimator scaleY = new PropertyAnimator(500, cl, "scaleY", cl.getScaleY(), 1.0f);
-                PropertyAnimator alpha = new PropertyAnimator(
-                        500, cl, "dimmedBitmapAlpha", cl.getDimmedBitmapAlpha(), 0.0f);
-                Sequencer.Builder b = s.play(translateX);
-                b.with(translateY);
-                b.with(scaleX);
-                b.with(scaleY);
-                b.with(alpha);
+                final CellLayout cl = (CellLayout)getChildAt(i);
+                final int duration =
+                    getResources().getInteger(R.integer.config_workspaceUnshrinkTime);
+                s.playTogether(
+                        new PropertyAnimator(duration, cl, "x", (float) screenWidth * i),
+                        new PropertyAnimator(duration, cl, "y", 0.0f),
+                        new PropertyAnimator(duration, cl, "scaleX", 1.0f),
+                        new PropertyAnimator(duration, cl, "scaleY", cl.getScaleY(), 1.0f),
+                        new PropertyAnimator(duration, cl, "dimmedBitmapAlpha", 0.0f));
             }
             s.addListener(mUnshrinkAnimationListener);
             s.start();