116

I'm using the new v7 appcompat library available starting from Android 4.3 (API level 18).

Regardless of what is specified in showAsAction for a menu item, it's not shown - it always creates the overflow menu icon, and puts even a single menu item under the menu.

Trying to add menu to an activity like this:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_sizes, menu);
    return true;
}

And here's my menu xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        android:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>

Is it a bug of the new support library v7, or just something wrong with the code? I've been using the similar code with ActionBarSherlock many times before.

1
  • 2
    For informational purposes - "..."always" is not recommended; it is better to use "ifRoom" and let the OS decide." Commented Jul 28, 2013 at 23:56

13 Answers 13

314

Probably you are missing required namespace:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:[yourapp]="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        [yourapp]:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>

Replace [yourapp] with your app name or any namespace your heart desires everywhere.

Other things worth checking:

  • See if your activity class extends ActionBarActivity

Check if the issue persists.


Android reference documentation: Adding Action Buttons. Here is the relevant text:

If your app is using the Support Library for compatibility on versions as low as Android 2.1, the showAsAction attribute is not available from the android: namespace. Instead this attribute is provided by the Support Library and you must define your own XML namespace and use that namespace as the attribute prefix. (A custom XML namespace should be based on your app name, but it can be any name you want and is only accessible within the scope of the file in which you declare it.)

11
  • 2
    That's what I've found out as well. Thank you - definitely accepted. But the showAsAction should use that custom namespace.
    – Mcingwe
    Commented Jul 28, 2013 at 23:44
  • 5
    'yourapp' means in String.xml <string name="app_name">yourapp</string> right?
    – LOG_TAG
    Commented Oct 15, 2013 at 5:58
  • 4
    Can someone explain WHY this works? Why is there a need to extend a custom namespace? Little confused.
    – dineth
    Commented Nov 8, 2013 at 1:45
  • 8
    @dineth appcompat is used as a library project. This means all its resources (strings, drawable, attributes...) are declared in your application namespace instead of the android namespace. As the showAsAction attribute did not exist in android-7, you have to use your app namespace
    – nicopico
    Commented Nov 14, 2013 at 16:53
  • 22
    Everyone says "custom namespace" or "a namespace that matches your app". But the namespace is always http://schemas.android.com/apk/res-auto in every example. That's not a custom one, or one that matches your app. That's the actual namespace from the documentation. I think everyone means a custom prefix, and it can actually be whatever you want. Is this true? Commented Jan 1, 2014 at 18:36
52

Figured out myself. With the support library v7 the showAsAction should go under a custom namespace like this:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:balloonberry="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        balloonberry:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>
3
  • 1
    'balloonberry' means in String.xml "<string name="app_name">balloonberry</string>" right?
    – LOG_TAG
    Commented Oct 15, 2013 at 5:59
  • 5
    @LOG_TAG - no, it should just be as entered above. This is not a string, but a namespace.
    – BeccaP
    Commented Oct 28, 2013 at 17:51
  • ohhh support v7 errr... its ok on support v4 Commented Oct 18, 2014 at 10:34
36

Also make sure that you use correct inflater in ActionBarActivity.onCreateOptionsMenu() method.

Correct solution:

MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.menu_example, menu);

Incorrect solution:

MenuInflater menuInflater = new MenuInflater(this);
menuInflater.inflate(R.menu.menu_example, menu);
4
  • 1
    I have passed all the above answers and another answers on stackoverflow, but the only thing that I was missing is you answer - getMenuInflater(). Thanks for sharing this.
    – Amt87
    Commented Dec 3, 2015 at 14:28
  • Thank you SO MUCH for this one. I converted all my 100+ menus to use a custom namespace and 1 stinkin' screen still wasn't working...turns out that 1 activity was using "new MenuInflater" instead of getMenuInflater(). Thanks a ton!
    – DiscDev
    Commented Dec 15, 2015 at 19:02
  • this is very important. I was using menuInflater creation (2 way). Thanks
    – wtk
    Commented Mar 10, 2018 at 8:20
  • thanks for this, really helped me. Btw, I have added additional answers for Kotlin users for this solution, you can check it below.
    – Yodi S.
    Commented Mar 5, 2022 at 4:43
26

For Fragments

Menus with custom namespace will prevent showAsAction from showing.

Using "android:" prefix for showAsAction will work, even though Android Studio will remark you should use a custom name space.

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/action_add_checkin"
          android:title="Add Checkin"
          android:orderInCategory="10"
          android:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add"/>
</menu>

This is using Android SDK 22 and Support v4 fragments, in case that makes any difference.

3
  • That's the only thing that solved My Problem (though it's showing this error). Thanks ! Commented Oct 30, 2015 at 11:20
  • 3
    You can suppress the error/warning in XML layout with tools:ignore="AppCompatResource" within the <item>. Docs here: tools.android.com/tips/lint/suppressing-lint-warnings
    – Baker
    Commented Oct 30, 2015 at 11:33
  • Your answer and Anton Kizema's are the right solutions for me. And also thanks for the tip tools:ignore.
    – hata
    Commented Jun 2, 2016 at 14:13
17

Got the same problem, but on Android 5. I have 3 items but OS ignored my attribute "always" and showed only 2 items. Here my solution:

  @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    Log.d(TAG, "onCreateOptionsMenu()");
    inflater.inflate(R.menu.your_menu, menu);
    for (int j = 0; j < menu.size(); j++) {
        MenuItem item = menu.getItem(j);
        Log.d(TAG, "set flag for " + item.getTitle());
        item.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS);
    }
}
1
  • 1
    setShowAsActionFlags() requires API 14, but this was still the best solution for me. Commented Feb 12, 2017 at 3:59
6

Also make sure that you have the correct path for the namespace. It will not give you an error message if it's wrong.

I had

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:myapp="http://schemas.android.com/res-auto">

instead of

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:myapp="http://schemas.android.com/apk/res-auto">

All I knew was that it wasn't working. Not sure how I managed to forget the /apk part of the path, but it happened. No error message, just an elusive bug to track down.

6

In my case, I had to remove from my app's build.gradle compile 'com.android.support:appcompat-v7:21.0.3'.

Notice: My min sdk = 14, and created project by android studio inserted my unnesessary dependancy.

After this replace you can write android:showAsAction="always"

2
  • Thanks it solved me out! This days maybe the best solution in most cases, because it's unnecessary to support Android versions prior to 4.0. Commented Aug 20, 2015 at 11:04
  • Your answer and Baker's are the right solutions for me.
    – hata
    Commented Jun 2, 2016 at 14:13
4

This might not be your case but I was using

new MenuInflater(this).inflate(R.menu.my_menu, menu);

changing it to

getMenuInflater().inflate(R.menu.my_menu, menu);

fixed the problem!

0
<?xml version="1.0" encoding="utf-8"?>
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    >
    <item
        android:id="@id/back"
        android:icon="@drawable/back"
        app:showAsAction="always"
        android:title="@string/back"/>
    <item
        android:id="@id/save"
        android:icon="@drawable/le_top_btn_icon_add"
        app:showAsAction="ifRoom"
        android:title="@string/save"/>
</menu>

don't work, with supportLibraryVersion = '25.1.0' compileSdkVersion = 25

see the "Warning"

Should use app:showAsAction with the appcompat library with xmlns:app="http://schemas.android.com/apk/res-auto" less... (Ctrl+F1)

When using the appcompat library,menu resources should refer to the showAsAction in the app: namespace, not the android: namespace.

Similarly,when not using the appcompat library, you should be using the android:showAsAction attribute.

I think the warn can be ignore.

0

add custom namespace like this to showAsAction and actionViewClass:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/search"
    android:title="@string/search"
    android:icon="@drawable/ic_search"
    app:showAsAction="collapseActionView|ifRoom"
    app:actionViewClass="android.widget.SearchView" />

0

I have solved it by replacing

android:showAsAction="ifRoom"

with

app:showAsAction="ifRoom"

That is menuitme xml look like,

<item android:id="@+id/action_refresh"
      android:title="Refresh"
      android:icon="@drawable/refresh2"
      app:showAsAction="ifRoom" />
0

The simplest way is Modify your code by adding

xmlns:app="http://schemas.android.com/apk/res-auto"

and change this code

android:showAsAction="always"

to

app:showAsAction="always"

and finally

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/menu_add_size"
        android:title="@string/menu_add_item"
        android:orderInCategory="10"
        app:showAsAction="always"
        android:icon="@android:drawable/ic_menu_add" />
</menu>
0

In Addition to @petrnohejl 's answer, in Kotlin you can just use this one line without initializing it first.

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.options_menu, menu)
        return true
    }

In my case, the menu item just ignored my app:showAsAction="always" or "ifRoom" and it really annoys me for hours. Then, after I searched in StackOverflow, I realized that I'm not using the correct MenuInflater.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.