Home > Enterprise >  How to remove the default background color for pressed PopupMenu items?
How to remove the default background color for pressed PopupMenu items?

Time:08-05

I've added rounded corners to a PopupMenu and it looks good, except now when I press a menu item, I get the ugly effect shown here:

enter image description here

In this example, while my finger is touching the third item, Android adds a default color behind the item, which shows through at the rounded corners. It also adds a rounded background to the item text, which partially covers the "glow" around the radio button.

This is my XML style for rounding the corners of the PopupMenu:

<style name="popover" parent="@android:style/Widget.PopupMenu">
    <item name="android:itemBackground">@android:color/transparent</item>
    <item name="android:colorBackground">@android:color/transparent</item>
    <item name="android:background">@drawable/alert_rounded_dark</item>
    <item name="android:textColor">#F9F9F9</item>
    <item name="android:textColorSecondary">#F9F9F9</item>
    <item name="colorAccent">#F9F9F9</item>
</style>

And alert_rounded_dark.xml:

<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#2B2B2B" />
    <corners android:radius="10dp" />
</shape>

It looks like Android is applying the rounded background style to the subviews of the popup menu, including the menu items and the menu item text. I tried to stop that by setting itemBackground to @android:color/transparent or @null, but that had no effect.

I tried changing the background attribute to windowBackground, popupBackground or panelBackground, but then the whole PopupMenu and its items were transparent.

I had a similar issue when rounding the corners of ListView rows, which I solved with this function of ListView:

this.listView?.setSelector(android.R.color.transparent)

I think this corresponds to the listSelector XML attribute, but I don't see a similar function or attribute in the class reference for PopupMenu, and using the listSelector attribute for a PopupMenu does nothing.

Is there another way to visually clean this up? I think stopping the inheritance of the rounded corner background and removing the pressed color would be best, but addressing either one should help a lot.

UPDATE

I found that changing itemBackground to the same color as the menu background stopped the system color from appearing behind items when pressing them (the four light gray corners you see in the picture), but that killed the rounded corners by adding an opaque, square background to every item. Then I tried setting itemBackground to a drawable selector that sets every state to the alert_rounded_dark drawable, to preserve the rounded corners, but that didn't suppress the system pressed color like setting a background color did.

CodePudding user response:

How do you apply the popover style to your PopupMenu?


If you use a ContextThemeWrapper, you can't directly apply PopupMenu style.
You need to assign your popover style to the popupMenuStyle attribute in the theme overlay. Here is how you can do it:

styles.xml

    <style name="ThemeOverlay.App.PopupMenu" parent="">
        <!-- if using android.widget.PopupMenu -->
        <item name="android:popupMenuStyle">@style/PopupMenu</item>
        <!-- if using androidx.appcompat.widget.PopupMenu -->
        <item name="popupMenuStyle">@style/PopupMenu</item>

        <!-- Other attributes -->
        <item name="android:textColor">#F9F9F9</item>
        <item name="android:textColorSecondary">#F9F9F9</item>
        <item name="colorAccent">#F9F9F9</item>
    </style>

    <style name="PopupMenu" parent="@android:style/Widget.PopupMenu">
        <item name="android:popupBackground">@drawable/alert_rounded_dark</item>
    </style>

And use it like so:

val menu = PopupMenu(
    // Using "ContextThemeWrapper" for PopupMenu customization
    ContextThemeWrapper(context, R.style.ThemeOverlay_App_PopupMenu),
    view // Your anchor view
)
menu.inflate(R.menu.your_menu_id)
menu.show()

Here is how it looks on my end:

popup_styling_example

Bonus:
If you wish to further customize RadioButton inside the PopupMenu, you can add radioButtonStyle attribute to the theme overlay, like so:

    <style name="ThemeOverlay.App.PopupMenu" parent="">
        ...
        <item name="radioButtonStyle">@style/YourCustomRadioButton</item>
    </style>
  • Related