summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorJorim Jaggi <jjaggi@google.com>2014-05-12 23:29:10 +0200
committerJorim Jaggi <jjaggi@google.com>2014-05-13 17:27:22 +0200
commit87cd5e71ec087e191b8baaa8913a878f92d4e10d (patch)
tree831e682598f7a5924b0e73b4272f4b296ec6c32a /packages
parent6dbae589731e9594b6e3c15dfc26797d9b6cda0c (diff)
downloadframeworks_base-87cd5e71ec087e191b8baaa8913a878f92d4e10d.zip
frameworks_base-87cd5e71ec087e191b8baaa8913a878f92d4e10d.tar.gz
frameworks_base-87cd5e71ec087e191b8baaa8913a878f92d4e10d.tar.bz2
Improve quick settings fling/expand animation.
Change-Id: I507970ad2d22712a140f2107b62e689c2f3d7d6e
Diffstat (limited to 'packages')
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java129
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java13
2 files changed, 133 insertions, 9 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
new file mode 100644
index 0000000..0606a94
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar;
+
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import android.view.animation.PathInterpolator;
+
+/**
+ * Utility class to calculate general fling animation when the finger is released.
+ */
+public class FlingAnimationUtils {
+
+ private static final float LINEAR_OUT_SLOW_IN_Y2 = 0.35f;
+ private static final float MAX_LENGTH_SECONDS = 0.4f;
+ private static final float MIN_VELOCITY_DP_PER_SECOND = 250;
+
+ /**
+ * Crazy math. http://en.wikipedia.org/wiki/B%C3%A9zier_curve
+ */
+ private static final float LINEAR_OUT_SLOW_IN_START_GRADIENT = 1/LINEAR_OUT_SLOW_IN_Y2;
+
+ private Interpolator mLinearOutSlowIn;
+ private Interpolator mFastOutSlowIn;
+ private float mMinVelocityPxPerSecond;
+
+ public FlingAnimationUtils(Context ctx) {
+ mLinearOutSlowIn = new PathInterpolator(0, 0, LINEAR_OUT_SLOW_IN_Y2, 1);
+ mFastOutSlowIn
+ = AnimationUtils.loadInterpolator(ctx, android.R.interpolator.fast_out_slow_in);
+ mMinVelocityPxPerSecond
+ = MIN_VELOCITY_DP_PER_SECOND * ctx.getResources().getDisplayMetrics().density;
+ }
+
+ /**
+ * Applies the interpolator and length to the animator, such that the fling animation is
+ * consistent with the finger motion.
+ *
+ * @param animator the animator to apply
+ * @param currValue the current value
+ * @param endValue the end value of the animator
+ * @param velocity the current velocity of the motion
+ */
+ public void apply(ValueAnimator animator, float currValue, float endValue, float velocity) {
+ float diff = Math.abs(endValue - currValue);
+ float velAbs = Math.abs(velocity);
+ float durationSeconds = LINEAR_OUT_SLOW_IN_START_GRADIENT * diff / velAbs;
+ if (durationSeconds <= MAX_LENGTH_SECONDS) {
+ animator.setInterpolator(mLinearOutSlowIn);
+ } else if (velAbs >= mMinVelocityPxPerSecond) {
+
+ // Cross fade between fast-out-slow-in and linear interpolator with current velocity.
+ durationSeconds = MAX_LENGTH_SECONDS;
+ VelocityInterpolator velocityInterpolator
+ = new VelocityInterpolator(durationSeconds, velAbs, diff);
+ InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator(
+ velocityInterpolator, mLinearOutSlowIn, mLinearOutSlowIn);
+ animator.setInterpolator(superInterpolator);
+ } else {
+
+ // Just use a normal interpolator which doesn't take the velocity into account.
+ durationSeconds = MAX_LENGTH_SECONDS;
+ animator.setInterpolator(mFastOutSlowIn);
+ }
+ animator.setDuration((long) (durationSeconds * 1000));
+ }
+
+ /**
+ * An interpolator which interpolates two interpolators with an interpolator.
+ */
+ private static final class InterpolatorInterpolator implements Interpolator {
+
+ private Interpolator mInterpolator1;
+ private Interpolator mInterpolator2;
+ private Interpolator mCrossfader;
+
+ InterpolatorInterpolator(Interpolator interpolator1, Interpolator interpolator2,
+ Interpolator crossfader) {
+ mInterpolator1 = interpolator1;
+ mInterpolator2 = interpolator2;
+ mCrossfader = crossfader;
+ }
+
+ @Override
+ public float getInterpolation(float input) {
+ float t = mCrossfader.getInterpolation(input);
+ return (1 - t) * mInterpolator1.getInterpolation(input)
+ + t * mInterpolator2.getInterpolation(input);
+ }
+ }
+
+ /**
+ * An interpolator which interpolates with a fixed velocity.
+ */
+ private static final class VelocityInterpolator implements Interpolator {
+
+ private float mDurationSeconds;
+ private float mVelocity;
+ private float mDiff;
+
+ private VelocityInterpolator(float durationSeconds, float velocity, float diff) {
+ mDurationSeconds = durationSeconds;
+ mVelocity = velocity;
+ mDiff = diff;
+ }
+
+ @Override
+ public float getInterpolation(float input) {
+ float time = input * mDurationSeconds;
+ return time * mVelocity / mDiff;
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 6132ed2..f19ce97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -32,6 +32,7 @@ import android.widget.LinearLayout;
import com.android.systemui.R;
import com.android.systemui.statusbar.ExpandableView;
+import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.GestureRecorder;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
@@ -53,8 +54,6 @@ public class NotificationPanelView extends PanelView implements
private int mNotificationTopPadding;
private boolean mAnimateNextTopPaddingChange;
- private Interpolator mExpansionInterpolator;
-
private int mTrackingPointer;
private VelocityTracker mVelocityTracker;
private boolean mTracking;
@@ -78,6 +77,7 @@ public class NotificationPanelView extends PanelView implements
private int mStackScrollerIntrinsicPadding;
private boolean mQsExpansionEnabled = true;
private ValueAnimator mQsExpansionAnimator;
+ private FlingAnimationUtils mFlingAnimationUtils;
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -115,8 +115,7 @@ public class NotificationPanelView extends PanelView implements
mNotificationTopPadding = getResources().getDimensionPixelSize(
R.dimen.notifications_top_padding);
mMinStackHeight = getResources().getDimensionPixelSize(R.dimen.collapsed_stack_height);
- mExpansionInterpolator = AnimationUtils.loadInterpolator(
- getContext(), android.R.interpolator.fast_out_slow_in);
+ mFlingAnimationUtils = new FlingAnimationUtils(getContext());
}
@Override
@@ -435,13 +434,9 @@ public class NotificationPanelView extends PanelView implements
}
}
private void flingSettings(float vel, boolean expand) {
-
- // TODO: Actually use velocity.
-
float target = expand ? mQsMaxExpansionHeight : mQsMinExpansionHeight;
ValueAnimator animator = ValueAnimator.ofFloat(mQsExpansionHeight, target);
- animator.setDuration(EXPANSION_ANIMATION_LENGTH);
- animator.setInterpolator(mExpansionInterpolator);
+ mFlingAnimationUtils.apply(animator, mQsExpansionHeight, target, vel);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {