Fix jumps in the beginning of animations

If the first draw frame of an animation is
expensive, which it often is, it causes a big
jump. Added a helper class which automatically
adjusts the animation start time if the first
frame is more than 16ms.

Change-Id: I100edbc41c2abe930a32d6bcf0a782ea9735f7f9
diff --git a/src/com/android/launcher2/LauncherAnimUtils.java b/src/com/android/launcher2/LauncherAnimUtils.java
index 9317c31..5055d35 100644
--- a/src/com/android/launcher2/LauncherAnimUtils.java
+++ b/src/com/android/launcher2/LauncherAnimUtils.java
@@ -21,6 +21,8 @@
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
+import android.view.View;
+import android.view.ViewTreeObserver;
 
 import java.util.HashSet;
 
@@ -47,6 +49,22 @@
         a.addListener(sEndAnimListener);
     }
 
+    // Helper method. Assumes a draw is pending, and that if the animation's duration is 0
+    // it should be cancelled
+    public static void startAnimationAfterNextDraw(final Animator animator, final View view) {
+        final ViewTreeObserver observer = view.getViewTreeObserver();
+        observer.addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
+                public void onDraw() {
+                    // Use this as a signal that the animation was cancelled
+                    if (animator.getDuration() == 0) {
+                        return;
+                    }
+                    animator.start();
+                    view.getViewTreeObserver().removeOnDrawListener(this);
+                }
+            });
+    }
+
     public static void onDestroyActivity() {
         HashSet<Animator> animators = new HashSet<Animator>(sAnimators);
         for (Animator a : animators) {
@@ -64,28 +82,40 @@
         return anim;
     }
 
-    public static ValueAnimator ofFloat(float... values) {
+    public static ValueAnimator ofFloat(View target, float... values) {
         ValueAnimator anim = new ValueAnimator();
         anim.setFloatValues(values);
         cancelOnDestroyActivity(anim);
         return anim;
     }
 
-    public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {
+    public static ObjectAnimator ofFloat(View target, String propertyName, float... values) {
         ObjectAnimator anim = new ObjectAnimator();
         anim.setTarget(target);
         anim.setPropertyName(propertyName);
         anim.setFloatValues(values);
         cancelOnDestroyActivity(anim);
+        new FirstFrameAnimatorHelper(anim, target);
         return anim;
     }
 
-    public static ObjectAnimator ofPropertyValuesHolder(Object target,
+    public static ObjectAnimator ofPropertyValuesHolder(View target,
             PropertyValuesHolder... values) {
         ObjectAnimator anim = new ObjectAnimator();
         anim.setTarget(target);
         anim.setValues(values);
         cancelOnDestroyActivity(anim);
+        new FirstFrameAnimatorHelper(anim, target);
+        return anim;
+    }
+
+    public static ObjectAnimator ofPropertyValuesHolder(Object target,
+            View view, PropertyValuesHolder... values) {
+        ObjectAnimator anim = new ObjectAnimator();
+        anim.setTarget(target);
+        anim.setValues(values);
+        cancelOnDestroyActivity(anim);
+        new FirstFrameAnimatorHelper(anim, view);
         return anim;
     }
 }