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

Commit 932005db authored by Selim Cinek's avatar Selim Cinek
Browse files

Placed the overflow indicator perfectly in the collapsed center

Previously, the state could be abitrary based on the width of the layout
this is now fixed.

Test: add high, low-priority notifications, observe perfect centering
Bug: 32437839
Change-Id: Id82d4aa87fe07f53bfe1b891a1ce2caa88d686dc
parent 17e1b695
Loading
Loading
Loading
Loading
+10 −1
Original line number Original line Diff line number Diff line
@@ -471,7 +471,15 @@ public class NotificationShelf extends ActivatableNotificationView {
                mShelfIcons.getWidth(),
                mShelfIcons.getWidth(),
                openedAmount);
                openedAmount);
        mShelfIcons.setActualLayoutWidth(width);
        mShelfIcons.setActualLayoutWidth(width);
        float padding = NotificationUtils.interpolate(mCollapsedIcons.getPaddingEnd(),
        boolean hasOverflow = mCollapsedIcons.hasOverflow();
        int collapsedPadding = mCollapsedIcons.getPaddingEnd();
        if (!hasOverflow) {
            // we have to ensure that adding the low priority notification won't lead to an
            // overflow
            collapsedPadding -= (1.0f + NotificationIconContainer.OVERFLOW_EARLY_AMOUNT)
                    * mCollapsedIcons.getIconSize();
        }
        float padding = NotificationUtils.interpolate(collapsedPadding,
                mShelfIcons.getPaddingEnd(),
                mShelfIcons.getPaddingEnd(),
                openedAmount);
                openedAmount);
        mShelfIcons.setActualPaddingEnd(padding);
        mShelfIcons.setActualPaddingEnd(padding);
@@ -479,6 +487,7 @@ public class NotificationShelf extends ActivatableNotificationView {
                mShelfIcons.getPaddingStart(), openedAmount);
                mShelfIcons.getPaddingStart(), openedAmount);
        mShelfIcons.setActualPaddingStart(paddingStart);
        mShelfIcons.setActualPaddingStart(paddingStart);
        mShelfIcons.setOpenedAmount(openedAmount);
        mShelfIcons.setOpenedAmount(openedAmount);
        mShelfIcons.setVisualOverflowAdaption(mCollapsedIcons.getVisualOverflowAdaption());
    }
    }


    public void setMaxLayoutHeight(int maxLayoutHeight) {
    public void setMaxLayoutHeight(int maxLayoutHeight) {
+51 −8
Original line number Original line Diff line number Diff line
@@ -38,6 +38,13 @@ import java.util.HashMap;
 * correctly on the screen.
 * correctly on the screen.
 */
 */
public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
    /**
     * A float value indicating how much before the overflow start the icons should transform into
     * a dot. A value of 0 means that they are exactly at the end and a value of 1 means it starts
     * 1 icon width early.
     */
    public static final float OVERFLOW_EARLY_AMOUNT = 0.2f;
    private static final int NO_VALUE = Integer.MIN_VALUE;
    private static final String TAG = "NotificationIconContainer";
    private static final String TAG = "NotificationIconContainer";
    private static final boolean DEBUG = false;
    private static final boolean DEBUG = false;
    private static final int CANNED_ANIMATION_DURATION = 100;
    private static final int CANNED_ANIMATION_DURATION = 100;
@@ -83,15 +90,16 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
    private final HashMap<View, IconState> mIconStates = new HashMap<>();
    private final HashMap<View, IconState> mIconStates = new HashMap<>();
    private int mDotPadding;
    private int mDotPadding;
    private int mStaticDotRadius;
    private int mStaticDotRadius;
    private int mActualLayoutWidth = -1;
    private int mActualLayoutWidth = NO_VALUE;
    private float mActualPaddingEnd = -1;
    private float mActualPaddingEnd = NO_VALUE;
    private float mActualPaddingStart = -1;
    private float mActualPaddingStart = NO_VALUE;
    private boolean mChangingViewPositions;
    private boolean mChangingViewPositions;
    private int mAddAnimationStartIndex = -1;
    private int mAddAnimationStartIndex = -1;
    private int mCannedAnimationStartIndex = -1;
    private int mCannedAnimationStartIndex = -1;
    private int mSpeedBumpIndex = -1;
    private int mSpeedBumpIndex = -1;
    private int mIconSize;
    private int mIconSize;
    private float mOpenedAmount = 0.0f;
    private float mOpenedAmount = 0.0f;
    private float mVisualOverflowAdaption;


    public NotificationIconContainer(Context context, AttributeSet attrs) {
    public NotificationIconContainer(Context context, AttributeSet attrs) {
        super(context, attrs);
        super(context, attrs);
@@ -226,7 +234,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
        int firstOverflowIndex = -1;
        int firstOverflowIndex = -1;
        int childCount = getChildCount();
        int childCount = getChildCount();
        float layoutEnd = getLayoutEnd();
        float layoutEnd = getLayoutEnd();
        float overflowStart = layoutEnd - mIconSize * 2.2f;
        float overflowStart = layoutEnd - mIconSize * (2 + OVERFLOW_EARLY_AMOUNT);
        boolean hasAmbient = mSpeedBumpIndex != -1 && mSpeedBumpIndex < getChildCount();
        boolean hasAmbient = mSpeedBumpIndex != -1 && mSpeedBumpIndex < getChildCount();
        float visualOverflowStart = 0;
        float visualOverflowStart = 0;
        for (int i = 0; i < childCount; i++) {
        for (int i = 0; i < childCount; i++) {
@@ -244,7 +252,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
                    || (translationX >= (noOverflowAfter ? layoutEnd - mIconSize : overflowStart)))) {
                    || (translationX >= (noOverflowAfter ? layoutEnd - mIconSize : overflowStart)))) {
                firstOverflowIndex = noOverflowAfter ? i - 1 : i;
                firstOverflowIndex = noOverflowAfter ? i - 1 : i;
                int totalDotLength = mStaticDotRadius * 6 + 2 * mDotPadding;
                int totalDotLength = mStaticDotRadius * 6 + 2 * mDotPadding;
                visualOverflowStart = overflowStart + mIconSize * 1.2f - totalDotLength / 2
                visualOverflowStart = overflowStart + mIconSize * (1 + OVERFLOW_EARLY_AMOUNT)
                        - totalDotLength / 2
                        - mIconSize * 0.5f + mStaticDotRadius;
                        - mIconSize * 0.5f + mStaticDotRadius;
                if (isAmbient) {
                if (isAmbient) {
                    visualOverflowStart = Math.min(translationX, visualOverflowStart
                    visualOverflowStart = Math.min(translationX, visualOverflowStart
@@ -253,6 +262,23 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
                    visualOverflowStart += (translationX - overflowStart) / mIconSize
                    visualOverflowStart += (translationX - overflowStart) / mIconSize
                            * (mStaticDotRadius * 2 + mDotPadding);
                            * (mStaticDotRadius * 2 + mDotPadding);
                }
                }
                if (mShowAllIcons) {
                    // We want to perfectly position the overflow in the static state, such that
                    // it's perfectly centered instead of measuring it from the end.
                    mVisualOverflowAdaption = 0;
                    if (firstOverflowIndex != -1) {
                        View firstOverflowView = getChildAt(i);
                        IconState overflowState = mIconStates.get(firstOverflowView);
                        float totalAmount = layoutEnd - overflowState.xTranslation;
                        float newPosition = overflowState.xTranslation + totalAmount / 2
                                - totalDotLength / 2
                                - mIconSize * 0.5f + mStaticDotRadius;
                        mVisualOverflowAdaption = newPosition - visualOverflowStart;
                        visualOverflowStart = newPosition;
                    }
                } else {
                    visualOverflowStart += mVisualOverflowAdaption * (1f - mOpenedAmount);
                }
            }
            }
            translationX += iconState.iconAppearAmount * view.getWidth();
            translationX += iconState.iconAppearAmount * view.getWidth();
        }
        }
@@ -293,14 +319,14 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
    }
    }


    private float getActualPaddingEnd() {
    private float getActualPaddingEnd() {
        if (mActualPaddingEnd < 0) {
        if (mActualPaddingEnd == NO_VALUE) {
            return getPaddingEnd();
            return getPaddingEnd();
        }
        }
        return mActualPaddingEnd;
        return mActualPaddingEnd;
    }
    }


    private float getActualPaddingStart() {
    private float getActualPaddingStart() {
        if (mActualPaddingStart < 0) {
        if (mActualPaddingStart == NO_VALUE) {
            return getPaddingStart();
            return getPaddingStart();
        }
        }
        return mActualPaddingStart;
        return mActualPaddingStart;
@@ -338,7 +364,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
    }
    }


    public int getActualWidth() {
    public int getActualWidth() {
        if (mActualLayoutWidth < 0) {
        if (mActualLayoutWidth == NO_VALUE) {
            return getWidth();
            return getWidth();
        }
        }
        return mActualLayoutWidth;
        return mActualLayoutWidth;
@@ -360,6 +386,23 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
        mOpenedAmount = expandAmount;
        mOpenedAmount = expandAmount;
    }
    }


    public float getVisualOverflowAdaption() {
        return mVisualOverflowAdaption;
    }

    public void setVisualOverflowAdaption(float visualOverflowAdaption) {
        mVisualOverflowAdaption = visualOverflowAdaption;
    }

    public boolean hasOverflow() {
        float width = (getChildCount() + OVERFLOW_EARLY_AMOUNT) * mIconSize;
        return width - (getWidth() - getActualPaddingStart() - getActualPaddingEnd()) > 0;
    }

    public int getIconSize() {
        return mIconSize;
    }

    public class IconState extends ViewState {
    public class IconState extends ViewState {
        public float iconAppearAmount = 1.0f;
        public float iconAppearAmount = 1.0f;
        public float clampedAppearAmount = 1.0f;
        public float clampedAppearAmount = 1.0f;