Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 593ee208 authored by Selim Cinek's avatar Selim Cinek
Browse files

Adapted the shade closing interpolator

The current interpolator wasn't working well
and was accelerating too much in certain cases.
We now finetuned those animations.

The animation has a slight acceleration to it for
slow swipes.

Test: close / open panel
Bug: 33652632
Fixes: 33652505
Change-Id: I62aa349b128dee9872b50b2af0ef419755ef7127
parent fcff4c64
Loading
Loading
Loading
Loading
+45 −11
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;

import com.android.systemui.Interpolators;
import com.android.systemui.statusbar.notification.NotificationUtils;

/**
 * Utility class to calculate general fling animation when the finger is released.
@@ -30,28 +31,43 @@ import com.android.systemui.Interpolators;
public class FlingAnimationUtils {

    private static final float LINEAR_OUT_SLOW_IN_X2 = 0.35f;
    private static final float LINEAR_OUT_SLOW_IN_X2_MAX = 0.68f;
    private static final float LINEAR_OUT_FASTER_IN_X2 = 0.5f;
    private static final float LINEAR_OUT_FASTER_IN_Y2_MIN = 0.4f;
    private static final float LINEAR_OUT_FASTER_IN_Y2_MAX = 0.5f;
    private static final float MIN_VELOCITY_DP_PER_SECOND = 250;
    private static final float HIGH_VELOCITY_DP_PER_SECOND = 3000;

    /**
     * Crazy math. http://en.wikipedia.org/wiki/B%C3%A9zier_curve
     */
    private static final float LINEAR_OUT_SLOW_IN_START_GRADIENT = 1.0f / LINEAR_OUT_SLOW_IN_X2;

    private Interpolator mLinearOutSlowIn;
    private static final float LINEAR_OUT_SLOW_IN_START_GRADIENT = 0.75f;
    private final float mSpeedUpFactor;

    private float mMinVelocityPxPerSecond;
    private float mMaxLengthSeconds;
    private float mHighVelocityPxPerSecond;
    private float mLinearOutSlowInX2;

    private AnimatorProperties mAnimatorProperties = new AnimatorProperties();
    private PathInterpolator mInterpolator;
    private float mCachedStartGradient = -1;
    private float mCachedVelocityFactor = -1;

    public FlingAnimationUtils(Context ctx, float maxLengthSeconds) {
        this(ctx, maxLengthSeconds, 0.0f);
    }

    /**
     * @param maxLengthSeconds the longest duration an animation can become in seconds
     * @param speedUpFactor a factor from 0 to 1 how much the slow down should be shifted towards
     *                      the end of the animation. 0 means it's at the beginning and no
     *                      acceleration will take place.
     */
    public FlingAnimationUtils(Context ctx, float maxLengthSeconds, float speedUpFactor) {
        mMaxLengthSeconds = maxLengthSeconds;
        mLinearOutSlowIn = new PathInterpolator(0, 0, LINEAR_OUT_SLOW_IN_X2, 1);
        mSpeedUpFactor = speedUpFactor;
        mLinearOutSlowInX2 = NotificationUtils.interpolate(LINEAR_OUT_SLOW_IN_X2,
                LINEAR_OUT_SLOW_IN_X2_MAX,
                mSpeedUpFactor);

        mMinVelocityPxPerSecond
                = MIN_VELOCITY_DP_PER_SECOND * ctx.getResources().getDisplayMetrics().density;
        mHighVelocityPxPerSecond
@@ -129,9 +145,14 @@ public class FlingAnimationUtils {
                * Math.sqrt(Math.abs(endValue - currValue) / maxDistance));
        float diff = Math.abs(endValue - currValue);
        float velAbs = Math.abs(velocity);
        float durationSeconds = LINEAR_OUT_SLOW_IN_START_GRADIENT * diff / velAbs;
        float velocityFactor = mSpeedUpFactor == 0.0f
                ? 1.0f : Math.min(velAbs / HIGH_VELOCITY_DP_PER_SECOND, 1.0f);
        float startGradient = NotificationUtils.interpolate(LINEAR_OUT_SLOW_IN_START_GRADIENT,
                1.0f / mLinearOutSlowInX2, velocityFactor);
        float durationSeconds = startGradient * diff / velAbs;
        Interpolator slowInInterpolator = getInterpolator(startGradient, velocityFactor);
        if (durationSeconds <= maxLengthSeconds) {
            mAnimatorProperties.interpolator = mLinearOutSlowIn;
            mAnimatorProperties.interpolator = slowInInterpolator;
        } else if (velAbs >= mMinVelocityPxPerSecond) {

            // Cross fade between fast-out-slow-in and linear interpolator with current velocity.
@@ -139,7 +160,7 @@ public class FlingAnimationUtils {
            VelocityInterpolator velocityInterpolator
                    = new VelocityInterpolator(durationSeconds, velAbs, diff);
            InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator(
                    velocityInterpolator, mLinearOutSlowIn, mLinearOutSlowIn);
                    velocityInterpolator, slowInInterpolator, Interpolators.LINEAR_OUT_SLOW_IN);
            mAnimatorProperties.interpolator = superInterpolator;
        } else {

@@ -151,6 +172,19 @@ public class FlingAnimationUtils {
        return mAnimatorProperties;
    }

    private Interpolator getInterpolator(float startGradient, float velocityFactor) {
        if (startGradient != mCachedStartGradient
                || velocityFactor != mCachedVelocityFactor) {
            float speedup = mSpeedUpFactor * (1.0f - velocityFactor);
            mInterpolator = new PathInterpolator(speedup,
                    speedup * startGradient,
                    mLinearOutSlowInX2, 1);
            mCachedStartGradient = startGradient;
            mCachedVelocityFactor = velocityFactor;
        }
        return mInterpolator;
    }

    /**
     * Applies the interpolator and length to the animator, such that the fling animation is
     * consistent with the finger motion for the case when the animation is making something
@@ -212,7 +246,7 @@ public class FlingAnimationUtils {
            VelocityInterpolator velocityInterpolator
                    = new VelocityInterpolator(durationSeconds, velAbs, diff);
            InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator(
                    velocityInterpolator, mLinearOutFasterIn, mLinearOutSlowIn);
                    velocityInterpolator, mLinearOutFasterIn, Interpolators.LINEAR_OUT_SLOW_IN);
            mAnimatorProperties.interpolator = superInterpolator;
        } else {

+0 −9
Original line number Diff line number Diff line
@@ -2006,15 +2006,6 @@ public class NotificationPanelView extends PanelView implements
        }
    }

    @Override
    protected float getCannedFlingDurationFactor() {
        if (mQsExpanded) {
            return 0.9f;
        } else {
            return 0.8f;
        }
    }

    @Override
    protected boolean fullyExpandedClearAllVisible() {
        return mNotificationStackScroller.isDismissViewNotGone()
+5 −8
Original line number Diff line number Diff line
@@ -180,8 +180,10 @@ public abstract class PanelView extends FrameLayout {

    public PanelView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mFlingAnimationUtils = new FlingAnimationUtils(context, 0.6f);
        mFlingAnimationUtilsClosing = new FlingAnimationUtils(context, 0.4f);
        mFlingAnimationUtils = new FlingAnimationUtils(context, 0.6f /* maxLengthSeconds */,
                0.6f /* speedUpFactor */);
        mFlingAnimationUtilsClosing = new FlingAnimationUtils(context, 0.5f /* maxLengthSeconds */,
                0.6f /* speedUpFactor */);
        mBounceInterpolator = new BounceInterpolator();
        mFalsingManager = FalsingManager.getInstance(context);
    }
@@ -704,9 +706,7 @@ public abstract class PanelView extends FrameLayout {

            // Make it shorter if we run a canned animation
            if (vel == 0) {
                animator.setDuration((long)
                        (animator.getDuration() * getCannedFlingDurationFactor()
                                / collapseSpeedUpFactor));
                animator.setDuration((long) (animator.getDuration() / collapseSpeedUpFactor));
            }
        }
        animator.addListener(new AnimatorListenerAdapter() {
@@ -1114,9 +1114,6 @@ public abstract class PanelView extends FrameLayout {
    public abstract void resetViews();

    protected abstract float getPeekHeight();

    protected abstract float getCannedFlingDurationFactor();

    /**
     * @return whether "Clear all" button will be visible when the panel is fully expanded
     */