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

Commit 1d76b705 authored by Lyn Han's avatar Lyn Han Committed by Automerger Merge Worker
Browse files

Merge "New shelf shape, notification corner animations on scroll" into sc-dev am: 2c4f9dda

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13996266

Change-Id: I6557257795e13bb2725767ddbb6bd06585c6894f
parents 3f8d9bec 2c4f9dda
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -181,6 +181,9 @@
    <!-- Radius for notifications corners without adjacent notifications -->
    <dimen name="notification_corner_radius">28dp</dimen>

    <!-- Distance over which notification corner animations run, near the shelf while scrolling. -->
    <dimen name="notification_corner_animation_distance">48dp</dimen>

    <!-- Radius for notifications corners with adjacent notifications -->
    <dimen name="notification_corner_radius_small">4dp</dimen>

+41 −21
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
    private int mCutoutHeight;
    private int mGapHeight;
    private int mIndexOfFirstViewInShelf = -1;

    private float mCornerAnimationDistance;
    private NotificationShelfController mController;

    public NotificationShelf(Context context, AttributeSet attrs) {
@@ -104,6 +104,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
        setClipToPadding(false);
        mShelfIcons.setIsStaticLayout(false);
        setBottomRoundness(1.0f, false /* animate */);
        setTopRoundness(1f, false /* animate */);

        // Setting this to first in section to get the clipping to the top roundness correct. This
        // value determines the way we are clipping to the top roundness of the overall shade
@@ -134,6 +135,8 @@ public class NotificationShelf extends ActivatableNotificationView implements
        mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
        mHiddenShelfIconSize = res.getDimensionPixelOffset(R.dimen.hidden_shelf_icon_size);
        mGapHeight = res.getDimensionPixelSize(R.dimen.qs_notification_padding);
        mCornerAnimationDistance = res.getDimensionPixelSize(
                R.dimen.notification_corner_animation_distance);

        mShelfIcons.setInNotificationIconShelf(true);
        if (!mShowNotificationShelf) {
@@ -256,7 +259,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
            boolean aboveShelf = ViewState.getFinalTranslationZ(child) > baseZHeight
                    || child.isPinned();
            boolean isLastChild = child == lastChild;
            float rowTranslationY = child.getTranslationY();
            final float viewStart = child.getTranslationY();

            final float inShelfAmount = updateShelfTransformation(i, child, scrollingFast,
                    expandingAnimated, isLastChild);
@@ -278,7 +281,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
                ExpandableNotificationRow expandableRow = (ExpandableNotificationRow) child;
                numViewsInShelf += inShelfAmount;
                int ownColorUntinted = expandableRow.getBackgroundColorWithoutTint();
                if (rowTranslationY >= shelfStart && mNotGoneIndex == -1) {
                if (viewStart >= shelfStart && mNotGoneIndex == -1) {
                    mNotGoneIndex = notGoneIndex;
                    setTintColor(previousColor);
                    setOverrideTintColor(colorTwoBefore, transitionAmount);
@@ -317,26 +320,44 @@ public class NotificationShelf extends ActivatableNotificationView implements
                notGoneIndex++;
            }

            final float viewEnd = viewStart + child.getActualHeight();
            final float cornerAnimationDistance = mCornerAnimationDistance
                    * mAmbientState.getExpansionFraction();
            final float cornerAnimationTop = shelfStart - cornerAnimationDistance;

            if (child instanceof ActivatableNotificationView) {
                ActivatableNotificationView anv =
                        (ActivatableNotificationView) child;
                if (anv.isFirstInSection() && previousAnv != null
                        && previousAnv.isLastInSection()) {
                    // If the top of the shelf is between the view before a gap and the view after a
                    // gap then we need to adjust the shelf's top roundness.
                    float distanceToGapBottom = child.getTranslationY() - getTranslationY();
                    float distanceToGapTop = getTranslationY()
                            - (previousAnv.getTranslationY() + previousAnv.getActualHeight());
                    if (distanceToGapTop > 0) {
                        // We interpolate our top roundness so that it's fully rounded if we're at
                        // the bottom of the gap, and not rounded at all if we're at the top of the
                        // gap (directly up against the bottom of previousAnv)
                        // Then we apply the same roundness to the bottom of previousAnv so that the
                        // corners join together as the shelf approaches previousAnv.
                        firstElementRoundness = (float) Math.min(1.0,
                                distanceToGapTop / mGapHeight);
                        previousAnv.setBottomRoundness(firstElementRoundness,
                                false /* don't animate */);

                if (viewStart < shelfStart
                        && !mHostLayoutController.isViewAffectedBySwipe(anv)
                        && !mAmbientState.isPulsing()
                        && !mAmbientState.isDozing()) {

                    if (viewEnd >= cornerAnimationTop) {
                        // Round bottom corners within animation bounds
                        final float changeFraction = MathUtils.saturate(
                                (viewEnd - cornerAnimationTop) / cornerAnimationDistance);
                        final float roundness = anv.isLastInSection() ? 1f : changeFraction * 1f;
                        anv.setBottomRoundness(roundness, false);

                    } else if (viewEnd < cornerAnimationTop) {
                        // Fast scroll skips frames and leaves corners with unfinished rounding.
                        // Reset top and bottom corners outside of animation bounds.
                        anv.setBottomRoundness(anv.isLastInSection() ? 1f : 0f, false);
                    }

                    if (viewStart >= cornerAnimationTop) {
                        // Round top corners within animation bounds
                        final float changeFraction = MathUtils.saturate(
                                (viewStart - cornerAnimationTop) / cornerAnimationDistance);
                        final float roundness = anv.isFirstInSection() ? 1f : changeFraction * 1f;
                        anv.setTopRoundness(roundness, false);

                    } else if (viewStart < cornerAnimationTop) {
                        // Fast scroll skips frames and leaves corners with unfinished rounding.
                        // Reset top and bottom corners outside of animation bounds.
                        anv.setTopRoundness(anv.isFirstInSection() ? 1f : 0f, false);
                    }
                }
                previousAnv = anv;
@@ -394,7 +415,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
    private void setFirstElementRoundness(float firstElementRoundness) {
        if (mFirstElementRoundness != firstElementRoundness) {
            mFirstElementRoundness = firstElementRoundness;
            setTopRoundness(firstElementRoundness, false /* animate */);
        }
    }

+1 −2
Original line number Diff line number Diff line
@@ -84,8 +84,7 @@ public class NotificationBackgroundView extends View {
            int bottom = mActualHeight;
            if (mBottomIsRounded
                    && mBottomAmountClips
                    && !mExpandAnimationRunning
                    && !mLastInSection) {
                    && !mExpandAnimationRunning) {
                bottom -= mClipBottomAmount;
            }
            int left = 0;
+29 −27
Original line number Diff line number Diff line
@@ -71,6 +71,13 @@ public class NotificationRoundnessManager {
        }
    }

    public boolean isViewAffectedBySwipe(ExpandableView expandableView) {
        return expandableView != null
                && (expandableView == mSwipedView
                    || expandableView == mViewBeforeSwipedView
                    || expandableView == mViewAfterSwipedView);
    }

    boolean updateViewWithoutCallback(ExpandableView view,
            boolean animate) {
        if (view == null
@@ -78,38 +85,35 @@ public class NotificationRoundnessManager {
                || view == mViewAfterSwipedView) {
            return false;
        }
        float topRoundness = getRoundness(view, true /* top */);
        float bottomRoundness = getRoundness(view, false /* top */);
        boolean topChanged = view.setTopRoundness(topRoundness, animate);
        boolean bottomChanged = view.setBottomRoundness(bottomRoundness, animate);
        boolean firstInSection = isFirstInSection(view, false /* exclude first section */);
        boolean lastInSection = isLastInSection(view, false /* exclude last section */);
        view.setFirstInSection(firstInSection);
        view.setLastInSection(lastInSection);
        return (firstInSection || lastInSection) && (topChanged || bottomChanged);

        final float topRoundness = getRoundness(view, true /* top */);
        final float bottomRoundness = getRoundness(view, false /* top */);

        final boolean topChanged = view.setTopRoundness(topRoundness, animate);
        final boolean bottomChanged = view.setBottomRoundness(bottomRoundness, animate);

        final boolean isFirstInSection = isFirstInSection(view);
        final boolean isLastInSection = isLastInSection(view);

        view.setFirstInSection(isFirstInSection);
        view.setLastInSection(isLastInSection);

        return (isFirstInSection || isLastInSection) && (topChanged || bottomChanged);
    }

    private boolean isFirstInSection(ExpandableView view, boolean includeFirstSection) {
        int numNonEmptySections = 0;
    private boolean isFirstInSection(ExpandableView view) {
        for (int i = 0; i < mFirstInSectionViews.length; i++) {
            if (view == mFirstInSectionViews[i]) {
                return includeFirstSection || numNonEmptySections > 0;
            }
            if (mFirstInSectionViews[i] != null) {
                numNonEmptySections++;
                return true;
            }
        }
        return false;
    }

    private boolean isLastInSection(ExpandableView view, boolean includeLastSection) {
        int numNonEmptySections = 0;
    private boolean isLastInSection(ExpandableView view) {
        for (int i = mLastInSectionViews.length - 1; i >= 0; i--) {
            if (view == mLastInSectionViews[i]) {
                return includeLastSection || numNonEmptySections > 0;
            }
            if (mLastInSectionViews[i] != null) {
                numNonEmptySections++;
                return true;
            }
        }
        return false;
@@ -172,10 +176,10 @@ public class NotificationRoundnessManager {
                || (view.isHeadsUpAnimatingAway()) && !mExpanded)) {
            return 1.0f;
        }
        if (isFirstInSection(view, true /* include first section */) && top) {
        if (isFirstInSection(view) && top) {
            return 1.0f;
        }
        if (isLastInSection(view, true /* include last section */) && !top) {
        if (isLastInSection(view) && !top) {
            return 1.0f;
        }
        if (view == mTrackedHeadsUp) {
@@ -229,10 +233,8 @@ public class NotificationRoundnessManager {
                                    : section.getLastVisibleChild());
                    if (newView == oldView) {
                        isStillPresent = true;
                        if (oldView.isFirstInSection() != isFirstInSection(oldView,
                                false /* exclude first section */)
                                || oldView.isLastInSection() != isLastInSection(oldView,
                                false /* exclude last section */)) {
                        if (oldView.isFirstInSection() != isFirstInSection(oldView)
                                || oldView.isLastInSection() != isLastInSection(oldView)) {
                            adjacentSectionChanged = true;
                        }
                        break;
+4 −0
Original line number Diff line number Diff line
@@ -740,6 +740,10 @@ public class NotificationStackScrollLayoutController {
        return true;
    }

    public boolean isViewAffectedBySwipe(ExpandableView expandableView) {
        return mNotificationRoundnessManager.isViewAffectedBySwipe(expandableView);
    }

    public void addOnExpandedHeightChangedListener(BiConsumer<Float, Float> listener) {
        mView.addOnExpandedHeightChangedListener(listener);
    }
Loading