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

Commit 429284a6 authored by Ioana Alexandru's avatar Ioana Alexandru
Browse files

[Notif redesign] Animate expander alignment in group header expansion

This change introduces a gradual transition when dragging to expand a
group, so the expand button doesn't just jump to its centered
position when the expansion is done. The arrow itself still only
switches positions once the transition is finished.

The on-click transition is not affected (i.e. it's still jumpy).

Bug: 378660052
Test: visual test
Flag: android.app.notifications_redesign_templates
Change-Id: I4a444111f3b3eaa57ce50015ef28694dc70090cf
parent 85bebef2
Loading
Loading
Loading
Loading
+25 −11
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ public class NotificationHeaderView extends RelativeLayout {
    private boolean mExpandOnlyOnButton;
    private boolean mAcceptAllTouches;
    private float mTopLineTranslation;
    private float mExpandButtonTranslation;

    ViewOutlineProvider mProvider = new ViewOutlineProvider() {
        @Override
@@ -212,34 +213,47 @@ public class NotificationHeaderView extends RelativeLayout {
        return mTopLineView;
    }

    /** The view containing the button to expand the notification. */
    public NotificationExpandButton getExpandButton() {
        return mExpandButton;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        measureTopLineTranslation();
    }

    private void measureTopLineTranslation() {
        if (!notificationsRedesignTemplates()) {
            return;
        if (notificationsRedesignTemplates()) {
            mTopLineTranslation = measureCenterTranslation(mTopLineView);
            mExpandButtonTranslation = measureCenterTranslation(mExpandButton);
        }
    }

        // When the top line is centered (see centerTopLine), its height is MATCH_PARENT
    private float measureCenterTranslation(View view) {
        // When the view is centered (see centerTopLine), its height is MATCH_PARENT
        int parentHeight = getMeasuredHeight();
        // When the top line is top-aligned, its height is WRAP_CONTENT
        float wrapContentHeight = mTopLineView.getMeasuredHeight();
        // When the view is top-aligned, its height is WRAP_CONTENT
        float wrapContentHeight = view.getMeasuredHeight();
        // Calculate the translation needed between the two alignments
        final MarginLayoutParams lp = (MarginLayoutParams) mTopLineView.getLayoutParams();
        mTopLineTranslation = abs((parentHeight - wrapContentHeight) / 2f - lp.topMargin);
        final MarginLayoutParams lp = (MarginLayoutParams) view.getLayoutParams();
        return abs((parentHeight - wrapContentHeight) / 2f - lp.topMargin);
    }

    /**
     * The vertical translation necessary between the two positions of the top line, to be used in
     * the animation. See also {@link this#centerTopLine(boolean)}.
     * the animation. See also {@link NotificationHeaderView#centerTopLine(boolean)}.
     */
    public float getTopLineTranslation() {
        return mTopLineTranslation;
    }

    /**
     * The vertical translation necessary between the two positions of the expander, to be used in
     * the animation. See also {@link NotificationHeaderView#centerTopLine(boolean)}.
     */
    public float getExpandButtonTranslation() {
        return mExpandButtonTranslation;
    }

    /**
     * This is used to make the low-priority header show the bolded text of a title.
     *
+30 −14
Original line number Diff line number Diff line
@@ -124,6 +124,7 @@ public class NotificationChildrenContainer extends ViewGroup
    private NotificationGroupingUtil mGroupingUtil;
    private ViewState mHeaderViewState;
    private ViewState mTopLineViewState;
    private ViewState mExpandButtonViewState;
    private int mClipBottomAmount;
    private boolean mIsMinimized;
    private OnClickListener mHeaderClickListener;
@@ -867,10 +868,7 @@ public class NotificationChildrenContainer extends ViewGroup
            }
        }
        if (mGroupHeader != null) {
            if (mHeaderViewState == null) {
                mHeaderViewState = new ViewState();
            }
            mHeaderViewState.initFrom(mGroupHeader);
            mHeaderViewState = initStateForGroupHeader(mHeaderViewState);

            if (mContainingNotification.hasExpandingChild()) {
                // Not modifying translationZ during expand animation.
@@ -882,22 +880,35 @@ public class NotificationChildrenContainer extends ViewGroup
            }
            mHeaderViewState.setYTranslation(mCurrentHeaderTranslation);
            mHeaderViewState.setAlpha(mHeaderVisibleAmount);
            // The hiding is done automatically by the alpha, otherwise we'll pick it up again
            // in the next frame with the initFrom call above and have an invisible header
            mHeaderViewState.hidden = false;

            if (notificationsRedesignTemplates()) {
                if (mTopLineViewState == null) {
                    mTopLineViewState = new ViewState();
                }
                mTopLineViewState.initFrom(mGroupHeader);
                mTopLineViewState = initStateForGroupHeader(mTopLineViewState);
                mTopLineViewState.setYTranslation(
                        mGroupHeader.getTopLineTranslation() * expandFactor);
                mTopLineViewState.hidden = false;

                mExpandButtonViewState = initStateForGroupHeader(mExpandButtonViewState);
                mExpandButtonViewState.setYTranslation(
                        mGroupHeader.getExpandButtonTranslation() * expandFactor);
            }
        }
    }

    /**
     * Initialise a new ViewState for the group header or its children, or update and return
     * {@code existingState} if not null.
     */
    private ViewState initStateForGroupHeader(ViewState existingState) {
        ViewState viewState = existingState;
        if (viewState == null) {
            viewState = new ViewState();
        }
        viewState.initFrom(mGroupHeader);
        // The hiding is done automatically by the alpha, otherwise we'll pick it up again
        // in the next frame with the initFrom call above and have an invisible header
        viewState.hidden = false;
        return viewState;
    }

    /**
     * When moving into the bottom stack, the bottom visible child in an expanded group adjusts its
     * height, children in the group after this are gone.
@@ -987,9 +998,14 @@ public class NotificationChildrenContainer extends ViewGroup
        if (mHeaderViewState != null) {
            mHeaderViewState.applyToView(mGroupHeader);
        }
        if (notificationsRedesignTemplates() && mTopLineViewState != null) {
        if (notificationsRedesignTemplates()) {
            if (mTopLineViewState != null) {
                mTopLineViewState.applyToView(mGroupHeader.getTopLineView());
            }
            if (mExpandButtonViewState != null) {
                mExpandButtonViewState.applyToView(mGroupHeader.getExpandButton());
            }
        }
        updateChildrenClipping();
    }

+1 −0
Original line number Diff line number Diff line
@@ -6679,6 +6679,7 @@ public class NotificationStackScrollLayout
        NotificationHeaderView header = childrenContainer.getGroupHeader();
        if (header != null) {
            resetYTranslation(header.getTopLineView());
            resetYTranslation(header.getExpandButton());
            header.centerTopLine(expanded);
        }
    }