Create an ActionBar icon with a text label in Android
UPDATE:
The majority of this article and the hours wasted writing, were basically for nothing.
Turns out, Android Studio supports assigning BOTH:
android:actionLayout
ANDapp:actionLayout
to a menu item.
I think we can all agree that this is absolutely HORRID. Supporting identical attributes that differ only by namespace is all but guaranteed to cause confusion and consternation — as it did for me.
Apparently, AppCompat
doesn’t support using android:
attributes. Why? Who knows.
The correct way to specify a custom menu item layout when using AppCompat
Toolbar or ActionBar is:
app:actionLayout
NOT
android:actionLayout
The rest of this article is valid, except where I complain that you must programmatically set the actionView
. In fact, to get your custom menu item layout to inflate properly, you just need the correct namespace. Jesus, Android.
ORIGINAL ARTICLE
Another in the never-ending, laughable morass of Android SDK gotchas, Android provides no support for one of the most fundamental and common patterns in all of computer programming:
Displaying a toolbar icon with a label
You have 3 choices for displaying a toolbar item:
- Text Only
- Icon Only
- Design your own menu item component from the ground up
Well, that third option is obviously horrid, but it’s all we get. So let’s dive in.
To design our own menu item component from scratch, we start by creating a custom XML layout for the menu item:
Here, we’ve generated the simplest possible custom menu item layout, containing a TextView
with an icon.
Then in our menu xml, set actionLayout
to our custom layout:
That should do it! The end. Thank you very much.
Android simply completely IGNORES the actionLayout
attribute we just set, and instead of rendering our custom menu item layout, it renders nothing at all.
This naturally begs the question: WTF is the actionLayout
attribute even for if it doesn’t do anything?
Well, it appears to be a design-time attribute ONLY. (wrong again, see above)
This naturally begs the question: Why is the actionLayout
attribute not part of the tools
namespace (like all the other design-time only attributes) instead of the android
namespace?
For this, I have no answer.
To actually USE the custom menu item layout in our toolbar, we’re FORCED to set the layout programmatically in onCreateOptionsMenu
. (wrong again, see above):
Because actionLayout
appears to be design-time only, we can simply omit it from our res/menu/act_menu.xml. And because our custom menu item layout will set the title of the menu item, we can simply omit the now useless title
attribute as well:
So, we’ve managed to create a menu item with both an icon and a label. But of course, we’re not done yet, because as soon as you implement your own custom menu item layout, you’re now in charge of EVERYTHING. ALL styling that would normally be applied to this toolbar/actionbar item is stripped away. Once I figure out how to restore the styling, I’ll update this article.
As stated in my love letter to the Android SDK, here’s another perfect example of Android’s complete lack of fundamental abstractions. Setting a toolbar icon with a text label has got to be one of the most fundamental needs in all of computer programming. Yet Android doesn’t support it unless you want to dive DEEP into layout and rendering and styling logic.
Dear God, if I could spend a single day developing for Android without little insanities like this chasing me around, my life would be much improved.