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

Commit 2c4f9dda authored by Lyn Han's avatar Lyn Han Committed by Android (Google) Code Review
Browse files

Merge "New shelf shape, notification corner animations on scroll" into sc-dev

parents e0f6dc07 80a42c0f
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -181,6 +181,9 @@
    <!-- Radius for notifications corners without adjacent notifications -->
    <!-- Radius for notifications corners without adjacent notifications -->
    <dimen name="notification_corner_radius">28dp</dimen>
    <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 -->
    <!-- Radius for notifications corners with adjacent notifications -->
    <dimen name="notification_corner_radius_small">4dp</dimen>
    <dimen name="notification_corner_radius_small">4dp</dimen>


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

    private float mCornerAnimationDistance;
    private NotificationShelfController mController;
    private NotificationShelfController mController;


    public NotificationShelf(Context context, AttributeSet attrs) {
    public NotificationShelf(Context context, AttributeSet attrs) {
@@ -104,6 +104,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
        setClipToPadding(false);
        setClipToPadding(false);
        mShelfIcons.setIsStaticLayout(false);
        mShelfIcons.setIsStaticLayout(false);
        setBottomRoundness(1.0f, false /* animate */);
        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
        // 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
        // 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);
        mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
        mHiddenShelfIconSize = res.getDimensionPixelOffset(R.dimen.hidden_shelf_icon_size);
        mHiddenShelfIconSize = res.getDimensionPixelOffset(R.dimen.hidden_shelf_icon_size);
        mGapHeight = res.getDimensionPixelSize(R.dimen.qs_notification_padding);
        mGapHeight = res.getDimensionPixelSize(R.dimen.qs_notification_padding);
        mCornerAnimationDistance = res.getDimensionPixelSize(
                R.dimen.notification_corner_animation_distance);


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


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


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

            if (child instanceof ActivatableNotificationView) {
            if (child instanceof ActivatableNotificationView) {
                ActivatableNotificationView anv =
                ActivatableNotificationView anv =
                        (ActivatableNotificationView) child;
                        (ActivatableNotificationView) child;
                if (anv.isFirstInSection() && previousAnv != null

                        && previousAnv.isLastInSection()) {
                if (viewStart < shelfStart
                    // If the top of the shelf is between the view before a gap and the view after a
                        && !mHostLayoutController.isViewAffectedBySwipe(anv)
                    // gap then we need to adjust the shelf's top roundness.
                        && !mAmbientState.isPulsing()
                    float distanceToGapBottom = child.getTranslationY() - getTranslationY();
                        && !mAmbientState.isDozing()) {
                    float distanceToGapTop = getTranslationY()

                            - (previousAnv.getTranslationY() + previousAnv.getActualHeight());
                    if (viewEnd >= cornerAnimationTop) {
                    if (distanceToGapTop > 0) {
                        // Round bottom corners within animation bounds
                        // We interpolate our top roundness so that it's fully rounded if we're at
                        final float changeFraction = MathUtils.saturate(
                        // the bottom of the gap, and not rounded at all if we're at the top of the
                                (viewEnd - cornerAnimationTop) / cornerAnimationDistance);
                        // gap (directly up against the bottom of previousAnv)
                        final float roundness = anv.isLastInSection() ? 1f : changeFraction * 1f;
                        // Then we apply the same roundness to the bottom of previousAnv so that the
                        anv.setBottomRoundness(roundness, false);
                        // corners join together as the shelf approaches previousAnv.

                        firstElementRoundness = (float) Math.min(1.0,
                    } else if (viewEnd < cornerAnimationTop) {
                                distanceToGapTop / mGapHeight);
                        // Fast scroll skips frames and leaves corners with unfinished rounding.
                        previousAnv.setBottomRoundness(firstElementRoundness,
                        // Reset top and bottom corners outside of animation bounds.
                                false /* don't animate */);
                        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;
                previousAnv = anv;
@@ -394,7 +415,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
    private void setFirstElementRoundness(float firstElementRoundness) {
    private void setFirstElementRoundness(float firstElementRoundness) {
        if (mFirstElementRoundness != firstElementRoundness) {
        if (mFirstElementRoundness != firstElementRoundness) {
            mFirstElementRoundness = firstElementRoundness;
            mFirstElementRoundness = firstElementRoundness;
            setTopRoundness(firstElementRoundness, false /* animate */);
        }
        }
    }
    }


+1 −2
Original line number Original line Diff line number Diff line
@@ -84,8 +84,7 @@ public class NotificationBackgroundView extends View {
            int bottom = mActualHeight;
            int bottom = mActualHeight;
            if (mBottomIsRounded
            if (mBottomIsRounded
                    && mBottomAmountClips
                    && mBottomAmountClips
                    && !mExpandAnimationRunning
                    && !mExpandAnimationRunning) {
                    && !mLastInSection) {
                bottom -= mClipBottomAmount;
                bottom -= mClipBottomAmount;
            }
            }
            int left = 0;
            int left = 0;
+29 −27
Original line number Original line 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 updateViewWithoutCallback(ExpandableView view,
            boolean animate) {
            boolean animate) {
        if (view == null
        if (view == null
@@ -78,38 +85,35 @@ public class NotificationRoundnessManager {
                || view == mViewAfterSwipedView) {
                || view == mViewAfterSwipedView) {
            return false;
            return false;
        }
        }
        float topRoundness = getRoundness(view, true /* top */);

        float bottomRoundness = getRoundness(view, false /* top */);
        final float topRoundness = getRoundness(view, true /* top */);
        boolean topChanged = view.setTopRoundness(topRoundness, animate);
        final float bottomRoundness = getRoundness(view, false /* top */);
        boolean bottomChanged = view.setBottomRoundness(bottomRoundness, animate);

        boolean firstInSection = isFirstInSection(view, false /* exclude first section */);
        final boolean topChanged = view.setTopRoundness(topRoundness, animate);
        boolean lastInSection = isLastInSection(view, false /* exclude last section */);
        final boolean bottomChanged = view.setBottomRoundness(bottomRoundness, animate);
        view.setFirstInSection(firstInSection);

        view.setLastInSection(lastInSection);
        final boolean isFirstInSection = isFirstInSection(view);
        return (firstInSection || lastInSection) && (topChanged || bottomChanged);
        final boolean isLastInSection = isLastInSection(view);

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

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


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


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


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

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