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

Commit cd4f87ef authored by Lyn Han's avatar Lyn Han
Browse files

Better overflow button

Overflow button as BadgedImageView
- BadgedImageView uses launcher’s icon factory to render overflow icon, which fixes the size and space inconsistencies between real bubbles and a bare ImageView
- BadgedImageView gives us access to the existing dot drawing logic, which we can later use to draw a dot on overflow button when overflow bubbles get updates
- Replace Bubble with BubbleViewProvider inside BadgedImageView so that BadgedImageView can access BubbleOverflow’s dot info

UI polish
- Set margins for overflow bubbles
- Set padding for overflow empty state
- Set overflow button and dot color to accent color from theme
- Render overflow button based on theme and dark mode; update on change

Bug: 149146374
Bug: 148878911
Test: manual - overflow button shape, icon color updates on theme change
Test: manual - overflow button color updates on dark mode change
Test: manual - overflow UI looks like mocks (specs not final)
Test: atest SystemUITests
Change-Id: I3d8829d56bce5c80936698a038438aff6db42d0f
parent 3cd75d77
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/bubble_overflow_recycler"
        android:layout_gravity="center_horizontal"
        android:nestedScrollingEnabled="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

@@ -32,6 +33,8 @@
        android:id="@+id/bubble_overflow_empty_state"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="@dimen/bubble_overflow_empty_state_padding"
        android:paddingRight="@dimen/bubble_overflow_empty_state_padding"
        android:orientation="vertical"
        android:gravity="center">

+2 −4
Original line number Diff line number Diff line
@@ -14,11 +14,9 @@
  ~ See the License for the specific language governing permissions and
  ~ limitations under the License
  -->
<ImageView
<com.android.systemui.bubbles.BadgedImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/bubble_overflow_button"
    android:layout_width="@dimen/individual_bubble_size"
    android:layout_height="@dimen/individual_bubble_size"
    android:src="@drawable/ic_bubble_overflow_button"
    android:scaleType="center"
    android:layout_gravity="end"/>
    android:src="@drawable/ic_bubble_overflow_button"/>
+9 −1
Original line number Diff line number Diff line
@@ -1128,8 +1128,10 @@
    <dimen name="bubble_padding_top">16dp</dimen>
    <!-- Size of individual bubbles. -->
    <dimen name="individual_bubble_size">60dp</dimen>
    <!-- Size of bubble bitmap. -->
    <dimen name="bubble_bitmap_size">52dp</dimen>
    <!-- Size of bubble icon bitmap. -->
    <dimen name="bubble_icon_bitmap_size">52dp</dimen>
    <dimen name="bubble_overflow_icon_bitmap_size">24dp</dimen>
    <!-- Extra padding added to the touchable rect for bubbles so they are easier to grab. -->
    <dimen name="bubble_touch_padding">12dp</dimen>
    <!-- Size of the circle around the bubbles when they're in the dismiss target. -->
@@ -1141,6 +1143,12 @@
    <dimen name="bubble_expanded_view_slop">8dp</dimen>
    <!-- Default (and minimum) height of the expanded view shown when the bubble is expanded -->
    <dimen name="bubble_expanded_default_height">180dp</dimen>
    <!-- Default height of bubble overflow -->
    <dimen name="bubble_overflow_height">380dp</dimen>
    <!-- Bubble overflow padding when there are no bubbles  -->
    <dimen name="bubble_overflow_empty_state_padding">16dp</dimen>
    <!-- Margin of overflow bubbles -->
    <dimen name="bubble_overflow_margin">16dp</dimen>
    <!-- Height of the triangle that points to the expanded bubble -->
    <dimen name="bubble_pointer_height">4dp</dimen>
    <!-- Width of the triangle that points to the expanded bubble -->
+6 −7
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@ package com.android.systemui.bubbles;

import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.Rect;
@@ -50,9 +49,9 @@ public class BadgedImageView extends ImageView {
    // Flyout gets shown before the dot
    private int mCurrentDotState = DOT_STATE_SUPPRESSED_FOR_FLYOUT;

    private Bubble mBubble;
    private BubbleViewProvider mBubble;

    private int mIconBitmapSize;
    private int mBubbleBitmapSize;
    private DotRenderer mDotRenderer;
    private DotRenderer.DrawParams mDrawParams;
    private boolean mOnLeft;
@@ -78,18 +77,18 @@ public class BadgedImageView extends ImageView {
    public BadgedImageView(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mIconBitmapSize = getResources().getDimensionPixelSize(R.dimen.bubble_icon_bitmap_size);
        mBubbleBitmapSize = getResources().getDimensionPixelSize(R.dimen.bubble_bitmap_size);
        mDrawParams = new DotRenderer.DrawParams();

        Path iconPath = PathParser.createPathFromPathData(
                getResources().getString(com.android.internal.R.string.config_icon_mask));
        mDotRenderer = new DotRenderer(mIconBitmapSize, iconPath, DEFAULT_PATH_SIZE);
        mDotRenderer = new DotRenderer(mBubbleBitmapSize, iconPath, DEFAULT_PATH_SIZE);
    }

    /**
     * Updates the view with provided info.
     */
    public void update(Bubble bubble) {
    public void update(BubbleViewProvider bubble) {
        mBubble = bubble;
        setImageBitmap(bubble.getBadgedImage());
        setDotState(DOT_STATE_SUPPRESSED_FOR_FLYOUT);
@@ -147,7 +146,7 @@ public class BadgedImageView extends ImageView {
     * @param iconPath The new icon path to use when calculating dot position.
     */
    void drawDot(Path iconPath) {
        mDotRenderer = new DotRenderer(mIconBitmapSize, iconPath, DEFAULT_PATH_SIZE);
        mDotRenderer = new DotRenderer(mBubbleBitmapSize, iconPath, DEFAULT_PATH_SIZE);
        invalidate();
    }

+11 −1
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ class Bubble implements BubbleViewProvider {
    private int mDotColor;
    private Path mDotPath;


    public static String groupId(NotificationEntry entry) {
        UserHandle user = entry.getSbn().getUser();
        return user.getIdentifier() + "|" + entry.getSbn().getPackageName();
@@ -111,6 +112,7 @@ class Bubble implements BubbleViewProvider {
        mSuppressionListener = listener;
    }

    @Override
    public String getKey() {
        return mKey;
    }
@@ -127,14 +129,17 @@ class Bubble implements BubbleViewProvider {
        return mEntry.getSbn().getPackageName();
    }

    @Override
    public Bitmap getBadgedImage() {
        return mBadgedImage;
    }

    @Override
    public int getDotColor() {
        return mDotColor;
    }

    @Override
    public Path getDotPath() {
        return mDotPath;
    }
@@ -150,10 +155,12 @@ class Bubble implements BubbleViewProvider {
    }

    @Nullable
    @Override
    public BadgedImageView getIconView() {
        return mIconView;
    }

    @Override
    @Nullable
    public BubbleExpandedView getExpandedView() {
        return mExpandedView;
@@ -240,6 +247,7 @@ class Bubble implements BubbleViewProvider {
     * Note that this contents visibility doesn't affect visibility at {@link android.view.View},
     * and setting {@code false} actually means rendering the expanded view in transparent.
     */
    @Override
    public void setContentVisibility(boolean visibility) {
        if (mExpandedView != null) {
            mExpandedView.setContentVisibility(visibility);
@@ -333,7 +341,8 @@ class Bubble implements BubbleViewProvider {
    /**
     * Whether the bubble for this notification should show a dot indicating updated content.
     */
    boolean showDot() {
    @Override
    public boolean showDot() {
        return mShowBubbleUpdateDot
                && !mEntry.shouldSuppressNotificationDot()
                && !shouldSuppressNotification();
@@ -484,6 +493,7 @@ class Bubble implements BubbleViewProvider {
        return Objects.hash(mKey);
    }

    @Override
    public void logUIEvent(int bubbleCount, int action, float normalX, float normalY, int index) {
        if (this.getEntry() == null
                || this.getEntry().getSbn() == null) {
Loading