11

I tried to change background of popupmenu, but my implementation does not work.

This is my code:

<style name="MyHoloLight" parent="android:Theme.Holo.Light">
    <item name="android:popupMenuStyle">@style/popupMenuStyle</item>
</style>
<style name="popupMenuStyle" parent="@android:style/Widget.PopupMenu">
    <item name="android:popupBackground">@color/bgPopumMenu</item>
</style>

Apply in AndroidManifest.xml

<application
        android:hardwareAccelerated="true"
        android:label="@string/app_name"
        android:icon="@drawable/ic_launcher"
        android:theme="@style/MyHoloLight">
Ritesh Gune
  • 16,050
  • 6
  • 41
  • 70
user1854307
  • 500
  • 3
  • 7
  • 20

11 Answers11

31

the following styles working perfectly for me.

<style name="popupMenuStyle" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textColor">@color/color_white</item>
    <item name="android:itemBackground">@color/color_red</item>
</style>

here, parent should be the AppTheme parent

and in your code use these lines.

Context wrapper = new ContextThemeWrapper(context, R.style.popupMenuStyle);
PopupMenu popup = new PopupMenu(wrapper, v);

i hope it will work.

Raju
  • 1,053
  • 2
  • 11
  • 17
  • This is probably the only answer which works without any hassle. Kudos! – Suhayl SH Nov 24 '16 at 08:08
  • I spend a lot of days trying to get menu color working. This solution is the only one perfectly working. I'm using AppCompact and MenuPopupHelper. Thanks to @Raju ! – Lisitso Dec 07 '16 at 18:30
7

If bgPopumMenu is your image then use this.

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

You need to apply your style to your AppTheme. So try this.

<style name="AppTheme" parent="android:Theme.Holo.Light">
<item name="android:popupMenuStyle">@style/popupMenuStyle</item>
</style>
<style name="popupMenuStyle" parent="@android:style/Widget.PopupMenu">
<item name="android:popupBackground">@color/bgPopumMenu</item>
</style>
Piyush
  • 23,959
  • 6
  • 36
  • 71
5

I made some changes of @Raju`s code and the following styles working for me,

Context wrapper = new ContextThemeWrapper(context,R.style.popupMenuStyle);
PopupMenu popup = new PopupMenu(wrapper, YourView);

and this is my style,

<style name="popupMenuStyle" parent="android:Theme.Holo.Light.DarkActionBar">
    <item name="android:popupMenuStyle">@style/MyApp.PopupMenu</item>
    <item name="android:textColor">@color/White</item>
</style>

<style name="MyApp.PopupMenu" parent="android:Widget.Holo.Light.ListPopupWindow">
<item name="android:popupBackground">@color/color_semi_transparent</item>       
</style>
varotariya vajsi
  • 3,579
  • 32
  • 35
1

If you are using custom theme :

  1. In Manifest : @style/MyMaterialTheme is my customized theme :

      <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/MyMaterialTheme">
    
  2. Use this code : R.style.popupMenuStyle for popup menu in java class :

Context wrapper = new ContextThemeWrapper(getContext(), R.style.popupMenuStyle);
PopupMenu popup = new PopupMenu(wrapper, v);

//Inflating the Popup using xml file
popup.getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu());

MenuPopupHelper menuHelper = new MenuPopupHelper(wrapper, (MenuBuilder) popup.getMenu(), v);
menuHelper.setForceShowIcon(true);
menuHelper.setGravity(Gravity.RIGHT);
  1. this is custom style of popup- menu for your own background drawable

<style name="popupMenuStyle" parent="@android:style/Widget.PopupMenu">
    <item name="android:popupBackground">@drawable/dropdown_bg</item>
</style>
  1. then change in your own theme "popupMenuStyle"

    <style name="MyMaterialTheme" parent="MyMaterialTheme.Base">
    
        </style>
    
        <style name="MyMaterialTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
            <item name="windowNoTitle">true</item>
            <item name="windowActionBar">false</item>
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorPrimary</item>
    
            <item name="popupMenuStyle">@style/popupMenuStyle</item>
            <item name="android:popupMenuStyle">@style/popupMenuStyle</item>
        </style>
    
Raptor
  • 48,613
  • 43
  • 209
  • 344
Heena Arora
  • 691
  • 8
  • 17
1

I SOLVED it,

PopupMenu popup = new PopupMenu(context, view);

In above code I used context of type Activity not of Context type.

Chill !

Ali Akram
  • 2,966
  • 1
  • 18
  • 29
0

what about this :

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    MenuInflater inflater=getMenuInflater();
    inflater.inflate(R.menu.menu,menu);
    setMenuBackground(); 
    return true;    
}

and write this in the setMenuBackground() method

protected void setMenuBackground(){                              
        getLayoutInflater().setFactory( new Factory() {  
            public View onCreateView(String name, Context context, AttributeSet attrs) {
                if ( name.equalsIgnoreCase( "com.android.internal.view.menu.IconMenuItemView" ) ) {
                    try { // Ask our inflater to create the view  
                        LayoutInflater f = getLayoutInflater();  
                        final View view = f.createView( name, null, attrs );  
                        /* The background gets refreshed each time a new item is added the options menu.  
                        * So each time Android applies the default background we need to set our own  
                        * background. This is done using a thread giving the background change as runnable 
                        * object */
                        new Handler().post( new Runnable() {  
                            public void run () {  
                                // sets the background here
                                view.setBackgroundResource( R.drawable.bgPopumMenu);
                                // sets the text color              
                                ((TextView) view).setTextColor(Color.BLACK);
                                // sets the text size              
                                ((TextView) view).setTextSize(18);
                }
                        } );  
                    return view;
                }
            catch ( InflateException e ) {}
            catch ( ClassNotFoundException e ) {}  
        } 
        return null;
    }}); 
}
Arshad Ali
  • 2,725
  • 9
  • 49
  • 86
Lucian Novac
  • 1,241
  • 12
  • 17
  • Error will occur: *A factory has already been set on this LayoutInflater* – Raptor Apr 13 '17 at 07:58
  • because of a small change on the support library, see this link for more details: http://stackoverflow.com/questions/13415284/java-lang-illegalstateexception-a-factory-has-already-been-set-on-this-layoutin – Lucian Novac Apr 24 '17 at 11:00
0

You cannot give android:popupBackground as just a color. You should use or create a drawable.

You can use this link http://jgilfelt.github.io/android-actionbarstylegenerator/ to generate your desired color. And set it to that drawable.

tasomaniac
  • 9,559
  • 5
  • 45
  • 79
0

Try to define android:actionBarWidgetTheme in your theme:

<style name="MyHoloLight" parent="android:Theme.Holo.Light">
    <item name="android:popupMenuStyle">@style/popupMenuStyle</item>
    <item name="android:actionBarWidgetTheme">@style/Theme.Example.Widget</item>
</style>
<style name="popupMenuStyle" parent="@android:style/Widget.PopupMenu">
    <item name="android:popupBackground">@color/bgPopumMenu</item>
</style>
<style name="Theme.Example.Widget" parent="@style/Theme.AppCompat">
    <item name="popupMenuStyle">@style/popupMenuStyle</item>
    <item name="dropDownListViewStyle">@style/DropDownListView.Example</item>
</style>
<style name="DropDownListView.Example" parent="@style/Widget.AppCompat.ListView.DropDown">
    <item name="android:listSelector">@color/bgPopumMenu_whenSelected</item>
</style>
paaacman
  • 2,872
  • 1
  • 16
  • 18
0

If bgPopumMenu is your drawable then use this

    <item name="android:panelBackground">@drawable/bgPopumMenu</item>

You just put that directly into your AppTheme like so

<style name="AppTheme" parent="android:Theme.Holo.Light">
    <item name="android:panelBackground">@drawable/bgPopumMenu</item>
</style>
Murphybro2
  • 1,539
  • 13
  • 30
0

You can easily create a style for popup menu and apply that style to a theme and you can assign the theme to the Activity/Parent Activity*** in the android manifest like this

<style name="MyThemePopup" parent="@style/AppTheme.NoActionBar">
    <item name="android:popupMenuStyle">@style/PopupMenu</item>
</style>

Create @style/PopupMenu like this

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

Assign the MyThemePopup theme to your Activity/Parent Activity*** in AndroidManifest as

<activity
            android:name=".Activity"
            android:label="@string/title_activity"
            android:screenOrientation="portrait"
            android:theme="@style/MyThemePopup"/>

***When you using the fragment apply the theme for the parent activity defined in AndroidManifest

Manoranjan
  • 623
  • 8
  • 13
0

just add below line into Style.xml and its working :

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- To change action bar menuItem BG -->
            <item name="android:itemBackground">@color/white</item>
 </style>
axita.savani
  • 415
  • 3
  • 19
  • This will change only an item's background not the whole menus background, so after doing this there'll be still some different colour margins left on top and bottom. – Kashish Sharma Apr 18 '20 at 06:31
  • You have to remove margin and it is working on popup-menu for all the item's background color will change.. also your app must use parent="Theme.AppCompat.Light.NoActionBar" this actionbar.. – axita.savani Apr 18 '20 at 07:48