Android 4.3 menu item showAsAction="always" ignored
AndroidMenuitemAndroid Support-LibraryAndroid Actionbar-CompatAndroid Problem Overview
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.
Android Solutions
Solution 1 - Android
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.)
Solution 2 - Android
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>
Solution 3 - Android
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);
Solution 4 - Android
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.
Solution 5 - Android
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);
}
}
Solution 6 - Android
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.
Solution 7 - Android
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"
Solution 8 - Android
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!
Solution 9 - Android
<?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.
Solution 10 - Android
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" />
Solution 11 - Android
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" />
Solution 12 - Android
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>
Solution 13 - Android
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.