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

Commit d2ad6230 authored by Selim Cinek's avatar Selim Cinek
Browse files

Tuned the heads up animations more

The previous animation was using the linear interpolator
for the shape change, which is now properly using the
existing interpolator. Also the roundedness is now using
the interpolator to feel more connected to the rest of
the animation.
This also fixes some bugs where the heads up was animating
it's corner roundedness immediately, before it was
decided whether we will animating away, leading to some issues.

Lastly, this also adds a failsafe for the roundedness, which
could become really large if the roundness was updated without
an animation, while an animation was running already.

Fixes: 187175147
Test: add hun, observe nice animation
Change-Id: I4561eed97387e3465e7ea61066bffa11d8e6bda0
parent 00630da0
Loading
Loading
Loading
Loading
+17 −25
Original line number Diff line number Diff line
@@ -60,12 +60,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
     */
    private static final float HORIZONTAL_ANIMATION_END = 0.2f;

    /**
     * At which point from [0,1] does the alpha animation end (or start when
     * expanding)? 1.0 meaning that it ends immediately and 0.0 that it is continuously animated.
     */
    private static final float ALPHA_ANIMATION_END = 0.0f;

    /**
     * At which point from [0,1] does the horizontal collapse animation start (or start when
     * expanding)? 1.0 meaning that it starts immediately and 0.0 that it is animated at all.
@@ -497,10 +491,10 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView

        float targetValue;
        if (isAppearing) {
            mCurrentAppearInterpolator = mSlowOutFastInInterpolator;
            mCurrentAppearInterpolator = Interpolators.FAST_OUT_SLOW_IN;
            targetValue = 1.0f;
        } else {
            mCurrentAppearInterpolator = Interpolators.FAST_OUT_SLOW_IN;
            mCurrentAppearInterpolator = mSlowOutFastInInterpolator;
            targetValue = 0.0f;
        }
        mAppearAnimator = ValueAnimator.ofFloat(mAppearAnimationFraction,
@@ -584,19 +578,21 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
    }

    private void updateAppearRect() {
        float inverseFraction = (1.0f - mAppearAnimationFraction);
        float translationFraction = mCurrentAppearInterpolator.getInterpolation(inverseFraction);
        float translateYTotalAmount = translationFraction * mAnimationTranslationY;
        mAppearAnimationTranslation = translateYTotalAmount;
        float interpolatedFraction = mCurrentAppearInterpolator.getInterpolation(
                mAppearAnimationFraction);
        mAppearAnimationTranslation = (1.0f - interpolatedFraction) * mAnimationTranslationY;
        final int actualHeight = getActualHeight();
        float bottom = actualHeight * mAppearAnimationFraction;
        float bottom = actualHeight * interpolatedFraction;

        setOutlineRect(0, mAppearAnimationTranslation,
                getWidth(), bottom + mAppearAnimationTranslation);
        setOutlineRect(0, mAppearAnimationTranslation, getWidth(),
                bottom + mAppearAnimationTranslation);
    }

    private float getAppearAnimationFraction() {
        return mAppearAnimationFraction >= 0 ? mAppearAnimationFraction : 1;
    private float getInterpolatedAppearAnimationFraction() {
        if (mAppearAnimationFraction >= 0) {
            return mCurrentAppearInterpolator.getInterpolation(mAppearAnimationFraction);
        }
        return 1.0f;
    }

    private void updateAppearAnimationAlpha() {
@@ -629,18 +625,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView

    @Override
    public float getCurrentBackgroundRadiusTop() {
        float fraction = getAppearAnimationFraction();
        return isHeadsUpAnimatingAway() || isHeadsUp()
                ? mOutlineRadius * fraction
                : super.getCurrentBackgroundRadiusTop();
        float fraction = getInterpolatedAppearAnimationFraction();
        return MathUtils.lerp(0, super.getCurrentBackgroundRadiusTop(), fraction);
    }

    @Override
    public float getCurrentBackgroundRadiusBottom() {
        float fraction = getAppearAnimationFraction();
        return isHeadsUpAnimatingAway() || isHeadsUp()
                ? mOutlineRadius * fraction
                : super.getCurrentBackgroundRadiusBottom();
        float fraction = getInterpolatedAppearAnimationFraction();
        return MathUtils.lerp(0, super.getCurrentBackgroundRadiusBottom(), fraction);
    }

    private void applyBackgroundRoundness(float topRadius, float bottomRadius) {
+20 −2
Original line number Diff line number Diff line
@@ -249,9 +249,18 @@ public abstract class ExpandableOutlineView extends ExpandableView {
    @Override
    public boolean setTopRoundness(float topRoundness, boolean animate) {
        if (mTopRoundness != topRoundness) {
            float diff = Math.abs(topRoundness - mTopRoundness);
            mTopRoundness = topRoundness;
            boolean shouldAnimate = animate;
            if (PropertyAnimator.isAnimating(this, TOP_ROUNDNESS) && diff > 0.5f) {
                // Fail safe:
                // when we've been animating previously and we're now getting an update in the
                // other direction, make sure to animate it too, otherwise, the localized updating
                // may make the start larger than 1.0.
                shouldAnimate = true;
            }
            PropertyAnimator.setProperty(this, TOP_ROUNDNESS, topRoundness,
                    ROUNDNESS_PROPERTIES, animate);
                    ROUNDNESS_PROPERTIES, shouldAnimate);
            return true;
        }
        return false;
@@ -286,9 +295,18 @@ public abstract class ExpandableOutlineView extends ExpandableView {
    @Override
    public boolean setBottomRoundness(float bottomRoundness, boolean animate) {
        if (mBottomRoundness != bottomRoundness) {
            float diff = Math.abs(bottomRoundness - mBottomRoundness);
            mBottomRoundness = bottomRoundness;
            boolean shouldAnimate = animate;
            if (PropertyAnimator.isAnimating(this, BOTTOM_ROUNDNESS) && diff > 0.5f) {
                // Fail safe:
                // when we've been animating previously and we're now getting an update in the
                // other direction, make sure to animate it too, otherwise, the localized updating
                // may make the start larger than 1.0.
                shouldAnimate = true;
            }
            PropertyAnimator.setProperty(this, BOTTOM_ROUNDNESS, bottomRoundness,
                    ROUNDNESS_PROPERTIES, animate);
                    ROUNDNESS_PROPERTIES, shouldAnimate);
            return true;
        }
        return false;
+0 −52
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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.notification.stack;

import android.graphics.Path;
import android.view.animation.PathInterpolator;

/**
 * An interpolator specifically designed for the appear animation of heads up notifications.
 */
public class HeadsUpAppearInterpolator extends PathInterpolator {

    private static float X1 = 250f;
    private static float X2 = 200f;
    private static float XTOT = (X1 + X2);;

    public HeadsUpAppearInterpolator() {
        super(getAppearPath());
    }

    private static Path getAppearPath() {
        Path path = new Path();
        path.moveTo(0, 0);
        float y1 = 90f;
        float y2 = 80f;
        path.cubicTo(X1 * 0.8f / XTOT, y1 / y2,
                X1 * 0.8f / XTOT, y1 / y2,
                X1 / XTOT, y1 / y2);
        path.cubicTo((X1 + X2 * 0.4f) / XTOT, y1 / y2,
                (X1 + X2 * 0.2f) / XTOT, 1.0f,
                1.0f , 1.0f);
        return path;
    }

    public static float getFractionUntilOvershoot() {
        return X1 / XTOT;
    }
}
+1 −2
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.notification.stack;

import android.content.res.Resources;
import android.util.MathUtils;
import android.view.View;

import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
@@ -199,7 +198,7 @@ public class NotificationRoundnessManager {
        mExpanded = expandedHeight != 0.0f;
        mAppearFraction = appearFraction;
        if (mTrackedHeadsUp != null) {
            updateView(mTrackedHeadsUp, true);
            updateView(mTrackedHeadsUp, false /* animate */);
        }
    }

+9 −3
Original line number Diff line number Diff line
@@ -544,7 +544,11 @@ public class NotificationStackScrollLayoutController {

                @Override
                public void onHeadsUpUnPinned(NotificationEntry entry) {
                    mNotificationRoundnessManager.updateView(entry.getRow(), true /* animate */);
                    ExpandableNotificationRow row = entry.getRow();
                    // update the roundedness posted, because we might be animating away the
                    // headsup soon, so no need to set the roundedness to 0 and then back to 1.
                    row.post(() -> mNotificationRoundnessManager.updateView(row,
                            true /* animate */));
                }

                @Override
@@ -553,7 +557,9 @@ public class NotificationStackScrollLayoutController {
                    NotificationEntry topEntry = mHeadsUpManager.getTopEntry();
                    mView.setNumHeadsUp(numEntries);
                    mView.setTopHeadsUpEntry(topEntry);
                    mNotificationRoundnessManager.updateView(entry.getRow(), false /* animate */);
                    generateHeadsUpAnimation(entry, isHeadsUp);
                    ExpandableNotificationRow row = entry.getRow();
                    mNotificationRoundnessManager.updateView(row, true /* animate */);
                }
            };

@@ -1238,7 +1244,7 @@ public class NotificationStackScrollLayoutController {
        return mView.getFirstChildNotGone();
    }

    public void generateHeadsUpAnimation(NotificationEntry entry, boolean isHeadsUp) {
    private void generateHeadsUpAnimation(NotificationEntry entry, boolean isHeadsUp) {
        mView.generateHeadsUpAnimation(entry, isHeadsUp);
    }

Loading