Create an ActionBar icon with a text label in Android

Robert Mirabelle
3 min readJan 21, 2021

UPDATE:

The majority of this article and the hours wasted writing, were basically for nothing.

Turns out, Android Studio supports assigning BOTH:

  • android:actionLayout AND
  • app: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:

res/layout/menu_item_new.xml

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:

res/menu/act_main.xml

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):

ActivityMain.kt

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.

--

--