OSDN Git Service

Use finger velocity for ExpandHelper
authorJorim Jaggi <jjaggi@google.com>
Sat, 26 Jul 2014 10:36:35 +0000 (12:36 +0200)
committerJorim Jaggi <jjaggi@google.com>
Sat, 26 Jul 2014 17:16:39 +0000 (17:16 +0000)
Makes sure that the animation continuing the expand has the exact
same velocity as the finger started the expand. At the end of the
animation, the velocity slows nicely down (reusing logic from
FlingAnimationUtils, yay!).

Change-Id: If9a286a1a3d1bde649cf0475367a63a2188ca3c0

packages/SystemUI/src/com/android/systemui/ExpandHelper.java

index bbda536..a26c534 100644 (file)
@@ -29,11 +29,13 @@ import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.ScaleGestureDetector;
 import android.view.ScaleGestureDetector.OnScaleGestureListener;
+import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
 
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
+import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.statusbar.policy.ScrollAdapter;
 
 public class ExpandHelper implements Gefingerpoken {
@@ -49,7 +51,7 @@ public class ExpandHelper implements Gefingerpoken {
     private static final String TAG = "ExpandHelper";
     protected static final boolean DEBUG = false;
     protected static final boolean DEBUG_SCALE = false;
-    private static final long EXPAND_DURATION = 250;
+    private static final float EXPAND_DURATION = 0.3f;
 
     // Set to false to disable focus-based gestures (spread-finger vertical pull).
     private static final boolean USE_DRAG = true;
@@ -112,6 +114,8 @@ public class ExpandHelper implements Gefingerpoken {
     private int mGravity;
 
     private ScrollAdapter mScrollAdapter;
+    private FlingAnimationUtils mFlingAnimationUtils;
+    private VelocityTracker mVelocityTracker;
 
     private OnScaleGestureListener mScaleGestureListener
             = new ScaleGestureDetector.SimpleOnScaleGestureListener() {
@@ -171,7 +175,6 @@ public class ExpandHelper implements Gefingerpoken {
         mScaler = new ViewScaler();
         mGravity = Gravity.TOP;
         mScaleAnimation = ObjectAnimator.ofFloat(mScaler, "height", 0f);
-        mScaleAnimation.setDuration(EXPAND_DURATION);
         mPopDuration = mContext.getResources().getInteger(R.integer.blinds_pop_duration_ms);
         mPullGestureMinXSpan = mContext.getResources().getDimension(R.dimen.pull_span_min);
 
@@ -179,6 +182,7 @@ public class ExpandHelper implements Gefingerpoken {
         mTouchSlop = configuration.getScaledTouchSlop();
 
         mSGD = new ScaleGestureDetector(context, mScaleGestureListener);
+        mFlingAnimationUtils = new FlingAnimationUtils(context, EXPAND_DURATION);
     }
 
     private void updateExpansion() {
@@ -260,6 +264,7 @@ public class ExpandHelper implements Gefingerpoken {
         if (!isEnabled()) {
             return false;
         }
+        trackVelocity(ev);
         final int action = ev.getAction();
         if (DEBUG_SCALE) Log.d(TAG, "intercept: act=" + MotionEvent.actionToString(action) +
                          " expanding=" + mExpanding +
@@ -279,6 +284,7 @@ public class ExpandHelper implements Gefingerpoken {
 
         if (mExpanding) {
             mLastMotionY = ev.getRawY();
+            maybeRecycleVelocityTracker(ev);
             return true;
         } else {
             if ((action == MotionEvent.ACTION_MOVE) && 0 != (mExpansionStyle & BLINDS)) {
@@ -323,15 +329,52 @@ public class ExpandHelper implements Gefingerpoken {
             case MotionEvent.ACTION_CANCEL:
             case MotionEvent.ACTION_UP:
                 if (DEBUG) Log.d(TAG, "up/cancel");
-                finishExpanding(false);
+                finishExpanding(false, getCurrentVelocity());
                 clearView();
                 break;
             }
             mLastMotionY = ev.getRawY();
+            maybeRecycleVelocityTracker(ev);
             return mExpanding;
         }
     }
 
+    private void trackVelocity(MotionEvent event) {
+        int action = event.getActionMasked();
+        switch(action) {
+            case MotionEvent.ACTION_DOWN:
+                if (mVelocityTracker == null) {
+                    mVelocityTracker = VelocityTracker.obtain();
+                } else {
+                    mVelocityTracker.clear();
+                }
+                mVelocityTracker.addMovement(event);
+                break;
+            case MotionEvent.ACTION_MOVE:
+                mVelocityTracker.addMovement(event);
+                break;
+            default:
+                break;
+        }
+    }
+
+    private void maybeRecycleVelocityTracker(MotionEvent event) {
+        if (event.getActionMasked() == MotionEvent.ACTION_CANCEL
+                || event.getActionMasked() == MotionEvent.ACTION_UP) {
+            mVelocityTracker.recycle();
+            mVelocityTracker = null;
+        }
+    }
+
+    private float getCurrentVelocity() {
+        if (mVelocityTracker != null) {
+            mVelocityTracker.computeCurrentVelocity(1000);
+            return mVelocityTracker.getYVelocity();
+        } else {
+            return 0f;
+        }
+    }
+
     public void setEnabled(boolean enable) {
         mEnabled = enable;
     }
@@ -349,6 +392,7 @@ public class ExpandHelper implements Gefingerpoken {
         if (!isEnabled()) {
             return false;
         }
+        trackVelocity(ev);
         final int action = ev.getActionMasked();
         if (DEBUG_SCALE) Log.d(TAG, "touch: act=" + MotionEvent.actionToString(action) +
                 " expanding=" + mExpanding +
@@ -438,11 +482,12 @@ public class ExpandHelper implements Gefingerpoken {
             case MotionEvent.ACTION_UP:
             case MotionEvent.ACTION_CANCEL:
                 if (DEBUG) Log.d(TAG, "up/cancel");
-                finishExpanding(false);
+                finishExpanding(false, getCurrentVelocity());
                 clearView();
                 break;
         }
         mLastMotionY = ev.getRawY();
+        maybeRecycleVelocityTracker(ev);
         return mResizedView != null;
     }
 
@@ -476,7 +521,7 @@ public class ExpandHelper implements Gefingerpoken {
         return true;
     }
 
-    private void finishExpanding(boolean force) {
+    private void finishExpanding(boolean force, float velocity) {
         if (!mExpanding) return;
 
         if (DEBUG) Log.d(TAG, "scale in finishing on view: " + mResizedView);
@@ -506,6 +551,7 @@ public class ExpandHelper implements Gefingerpoken {
                     mScaleAnimation.removeListener(this);
                 }
             });
+            mFlingAnimationUtils.apply(mScaleAnimation, currentHeight, targetHeight, velocity);
             mScaleAnimation.start();
         } else {
             mCallback.setUserLockedChild(mResizedView, false);
@@ -529,7 +575,7 @@ public class ExpandHelper implements Gefingerpoken {
      * Use this to abort any pending expansions in progress.
      */
     public void cancel() {
-        finishExpanding(true);
+        finishExpanding(true, 0f /* velocity */);
         clearView();
 
         // reset the gesture detector