The Unknown Style: actionBarWidgetTheme

One of the cooler features I've found in the Android Action Bar is grouped menu items. If you group together a series of menu items in a submenu, you get a pretty popup of those items. For example, if you set a submenu with android:checkableBehavior="single" then it'll have a radio button next to each item in the popup menu:

I wanted to reskin the RadioButton so that they all looked Holo, even on versions using ActionBarSherlock. Naturally, I turned to my theme and set the radioButtonStyle. However, the code below did not work:

<style name="MyTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
  <item name="android:radioButtonStyle">@style/MyRadioButtonStyle</item>
</style>

<style name="MyRadioButtonStyle" parent="@android:style/Widget.CompoundButton.RadioButton">
  <item name="android:button">@drawable/my_radio_button</item>
</style>

I was fairly lost for a few hours because radioButtonStyle was clearly working on everything except for the widget popup. I could insert RadioButtons into my Activity and they'd pick up the new style, but the old style would remain for the action bar. What was going on?

The culprit is android:actionBarWidgetTheme.

Introduced in API 14, what it does is let you style Views inflated by the action bar separately from the rest of your Application or Activity. This is a neat trick, but if you don't know it exists, you could easily get lost on why your styles aren't applying to action bar Views.

If android:actionBarWidgetTheme is undefined, it falls back to the current theme's values. For most Android themes, that means you're fine. But in the case ofTheme.Holo.Light.DarkActionBar, it does set the actionBarWidgetTheme to @android:style/Theme.Holo. As a result, it will not fallback to your theme's default value.

I solved the problem by setting my own actionBarWidgetTheme that is a sub-style of the original actionBarWidgetTheme:

<style name="MyTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
  <item name="android:actionBarWidgetTheme">@style/MyActionBarWidgetTheme</item>
</style>

<style name="MyActionBarWidgetTheme" parent="@android:style/Theme.Holo">
  <item name="android:radioButtonStyle">@style/MyRadioButtonStyle</item>
</style>

It's important to properly parent the actionBarWidgetTheme with whatever the theme was previously setting as its parent; otherwise you may miss out on some styling elsewhere.