What is the correct way to apply a round, colored background to a Material PopupMenu Component?

Viewed 211

I am trying to make a popup menu with rounded corners and custom font. I am using a Material Menu from material.io. I want to acheive something like this:

enter image description here

What I have tried so far is to use PopupMenu and add styling parameters using a custom background drawable:

  1. Seeing answers in this question, I used ContextThemeWrapper so that my styling actually takes effect. Without this, style changes are not working
    private fun showAddGoalsMenu(view: View) {
        val wrapper = ContextThemeWrapper(context, R.style.PopupMenu)
        val popupMenu = PopupMenu(wrapper, view)
        popupMenu.inflate(R.menu.menu_add_goals)

        ...
    }
  1. From this material.io menu theming example, I tried to set the properties popupMenuBackground in the main app style, and also tried setting android:popupBackground in an individual style. But the background doesn't apply:

enter image description here

  1. From other answers (question 1, question 2, question 3), I found other attributes like background, android:background, itemBackground, android:itemBackground. From this,
  • background and android:background are only good for setting colors. If I set a custom drawable to background, it messes up the items as well:

enter image description here

  • itemBackground and android:itemBackground only set backgrounds to individual items. So if I apply a round background, the result looks like this:

enter image description here

My style code currently looks like this. According to what I have read so far, this should work. But .... sigh. I have commented out all experiments I did.

    <style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorSecondary">@color/colorSecondary</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="bottomNavigationStyle">@style/Widget.App.BottomNavigationView</item>

        <!--<item name="textAppearanceLargePopupMenu">@style/TextAppearance.App.Subtitle1</item>-->
        <!--<item name="textAppearanceSmallPopupMenu">@style/TextAppearance.App.Subtitle1</item>-->
        <!--<item name="popupMenuBackground">@drawable/custom_popup_background</item>-->
        <item name="popupMenuStyle">@style/PopupMenu</item>
    </style>

    <style name="PopupMenu" parent="Widget.MaterialComponents.PopupMenu">
        <item name="android:dropDownHorizontalOffset">-4dp</item>
        <item name="android:dropDownVerticalOffset">4dp</item>
        <item name="android:popupBackground">@drawable/custom_popup_background</item>
        <!--<item name="android:itemBackground">@drawable/black_popup_background</item>-->
        <item name="popupMenuBackground">@drawable/custom_popup_background</item>
        <!--<item name="background">@color/colorPrimary</item>-->
        <!--<item name="android:background">@drawable/custom_popup_background</item>-->
        <item name="android:background">@color/colorPrimary</item>-->
<!--        <item name="itemBackground">@drawable/black_popup_background</item>-->
        <item name="textAppearanceLargePopupMenu">@style/TextAppearance.App.Subtitle1</item>
        <item name="textAppearanceSmallPopupMenu">@style/TextAppearance.App.Subtitle1</item>
    </style>


    <style name="TextAppearance.App.Subtitle1" parent="TextAppearance.MaterialComponents.Subtitle1">
        <item name="fontFamily">@font/amaranth</item>
        <item name="android:fontFamily">@font/amaranth</item>
        <item name="android:textColor">#1E2D58</item>
    </style>

And here is my custom background drawable

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/colorPrimary"/>
    <corners
        android:radius="16dp"/>
    <padding
        android:bottom="8dp"
        android:top="8dp"/>
</shape>

For testing itemBackground, I created a black_popup_background.xml

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/colorSecondary"/>
    <corners
        android:radius="16dp"/>
    <padding
        android:bottom="8dp"
        android:top="8dp"/>
</shape>

And the output I am getting is:

enter image description here

I have no clue what I am doing wrong. Thanks for all help in advance!

1 Answers

For anyone who faces this issue later.

The mistake I was doing was using android.widget.PopupMenu in my code instead of androidx.appcompat.widget.PopupMenu. Once I replaced this usage, the styling worked.

Ultimately, my style looks same as mentioned here.

Related