8

In my application I am showing a contextual action bar and because I don't have room for all the actions, some of them are accessed under the overflow menu button. Now I want to style the overflow menu and change its background. My theme inherits from Theme.AppCompat, and I have these styles defined:

<item name="android:popupMenuStyle">@style/PopupMenu</item>
<item name="android:listPopupWindowStyle">@style/PopupMenu</item>
<item name="android:dropDownListViewStyle">@style/DropDownListView</item>

<style name="PopupMenu" parent="Widget.AppCompat.PopupMenu">
    <!--<item name="android:popupBackground">@color/dark_color</item>-->
    <item name="android:textColor">?android:textColorPrimary</item>
    <item name="android:dropDownSelector">?popupItemBackground</item>
</style>

<style name="DropDownListView" parent="Widget.AppCompat.ListView.DropDown">
    <item name="android:listSelector">?popupItemBackground</item>
    <item name="android:divider">@null</item>
    <item name="android:dividerHeight">0dp</item>
</style>

The other menus in my application (overflow menus in action bar and other) are styled, but the contextual action bar's overflow menu is not. What should I do?

Sandra
  • 4,239
  • 10
  • 47
  • 80
  • Have you made any progress on this? I found `actionModePopupWindowStyle` in `platform_frameworks_base/core/res/res/values/themes.xml` and `Widget.PopupWindow` in `platform_frameworks_base/core/res/res/values/styles.xml` but overriding it in my styles doesn't seem to have an effect. – JDJ Dec 18 '14 at 20:42
  • I haven't found a solution yet... – Sandra Dec 25 '14 at 10:34
  • @JDJ I found a solution. See my answer.. – Sandra Jan 15 '15 at 11:00

3 Answers3

2

To change the overflow menu background, you'll need to override attribute actionOverflowMenuStyle:

<!-- add to your parent style -->
<item name="actionOverflowMenuStyle">@style/LStyled.PopupMenu.OverflowMenu</item>

<style name="LStyled.PopupMenu.OverflowMenu" parent="@style/Widget.AppCompat.PopupMenu.Overflow">
    <!-- 'overlapAnchor' changes position of the popup -->
    <!-- true - popup will be shown over the overflow button -->
    <!-- false - popup will be shown below the overflow button -->
    <item name="overlapAnchor">false</item>
    <item name="android:popupBackground">@drawable/bg_cab_popup</item>
</style>

Drawable bg_cab_popup can be any kind of drawable. But, using a 9-patch makes sense.

If you need to change anything other than the background, please leave me a comment.

Vikram
  • 51,313
  • 11
  • 93
  • 122
  • I was trying your solution with entering a colour value for popupBackground and did not worked as expected. The outcome was some kind of doubled, wrong looking background for the overflow menu, but it did change it. When I try with a drawable resource, it works. But then I need to imitate the background of the other menus in my application, which have the default form (I just change the colour). Can I just change the colour here also somehow or should I look for the android resource they use for menu's backgrounds? If that is the case where can I find it? Thx – Sandra Jan 14 '15 at 12:51
  • @Sandra I haven't tried passing a color value in place of a drawable. The problem could be that `ColorDrawable` (this is what a color value is finally converted to) does not have intrinsic width and height. I use Photoshop for most image processing. The obvious benefit is that you can have completely custom themes. Something like this: [Overflow menu Bg using a 9patch](http://pho.to/8jgBs). – Vikram Jan 28 '15 at 18:10
2

I finally have a solution. It seems that you need to add this to your theme:

<item name="actionBarPopupTheme">@style/ThemeOverlay.My</item>

Where:

<style name="ThemeOverlay.My" parent="ThemeOverlay.AppCompat">
    <item name="android:colorBackground">@color/my_theme_background</item>
</style>

The colorBackground attribute can take any color value that you like and with this you have the contextual action button's overflow menu styled.

Sandra
  • 4,239
  • 10
  • 47
  • 80
0

I'm going to assume you're using the latest (21.x.x) appcompat-v7 library and have adpoted the new Toolbar widget. To achieve what you want you don't modify your main app theme (except for the text selection action mode) but apply a style to the Toolbar element in your layout (style="@style/Widget.YourApp.Toolbar"). The style definition may look similar to this:

<style name="Widget.YourApp.Toolbar" parent="Widget.AppCompat.Toolbar">
  <item name="android:background">#111</item>
  <item name="android:elevation" tools:ignore="NewApi">8dp</item>
  <item name="theme">@style/ThemeOverlay.YourApp.ActionBar</item>
  <item name="popupTheme">@style/ThemeOverlay.YourApp</item>
</style>

For what you're trying to achieve the popupTheme is the most important attribute. It points to another style definition which will describe the look of the toolbar's popup menu.

<style name="ThemeOverlay.YourApp" parent="ThemeOverlay.AppCompat">
  <item name="android:colorBackground">#f00</item>
  <item name="android:textColor">#ff0</item>
</style>

Important: Notice that you'll be using this as a theme not a style. When you apply a style the attributes are set only to the one layout element you specify it at. When you apply a theme the attributes propagate to all its children. That's why when using themes you never override the background (which would cause overdraw and undesired looks) in favor of more specific attributes like windowBackground or colorBackground (which apply only to the relevant top element).

To make this example complete I'll include a toolbar theme as well:

<style name="ThemeOverlay.YourApp.ActionBar" parent="ThemeOverlay.AppCompat.ActionBar">
  <!-- these color action bar title and subtitle -->
  <item name="android:textColorPrimary">#00f</item>
  <item name="android:textColorSecondary">#0ff</item>
  <!-- this colors the icons (apply manual tinting for non-appcompat icons programmatically) -->
  <item name="colorControlNormal">#0f0</item>
  <!-- bug in the library - the overflow icon on Lollipop will now respect the above -->
  <item name="android:colorControlNormal" tools:ignore="NewApi">?colorControlNormal</item>
  <!-- these color the text of action items -->
  <item name="actionMenuTextColor">?colorControlNormal</item>
</style>

Remember: When using custom text colors, use a selector and define the disabled color as well (doubly so if you're using the color on a button or in a menu).

EDIT

The above solution is said not to apply to contextual action bar or action mode popup. I found out that it's controlled by the following attribute defined on the activity theme:

<item name="actionModePopupWindowStyle">?attr/popupWindowStyle</item>

The default value points to @style/Widget.PopupMenu which is defined as follows:

<style name="Widget.PopupWindow">
    <item name="popupBackground">@drawable/editbox_dropdown_background_dark</item>
    <item name="popupAnimationStyle">@style/Animation.PopupWindow</item>
</style>

Create a custom style based on Widget.PopupWindow and point to it from actionModePopupWindowStyle.

Eugen Pechanec
  • 37,669
  • 7
  • 103
  • 124
  • The solution you are suggesting works fine for the toolbar and its overflow menu, but does not work for the overflow menu in the CAB. I tried it, and the contextual action bar's menu is still not styled... – Sandra Jan 08 '15 at 14:06
  • Please see the updated answer. The action mode requires "old school" styling. – Eugen Pechanec Jan 08 '15 at 16:31
  • Thank for your help so far, but I still can't get it to work. I implemented actionModePopupWindowStyle in my activity's theme, and pointed it to my custom style that looks something like this: . This still does not provide styling for the contextual overflow menu:(( – Sandra Jan 13 '15 at 15:52
  • Try putting the `actionModePopupWindowStyle` to the `Toolbar` instead of the `Activity`. – Eugen Pechanec Jan 13 '15 at 16:46