44

I want to add menu handler to my project. I read http://developer.android.com/guide/topics/ui/menus.html too, its very simple but the icon is not shown. I am very confused. I even added a menu item programmatically.

My code is:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    menu.add(0, 0, 0, "Quit").setIcon(R.drawable.ic_launcher);
    getMenuInflater().inflate(R.layout.menu, menu);
    return true;
}

and in xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Single menu item 
         Set id, icon and Title for each menu item 
    -->
    <item android:id="@+id/menu_bookmark" 
          android:icon="@drawable/update"
          android:title="@string/Update" />

</menu>
Dave Thomas
  • 3,667
  • 2
  • 33
  • 41
Shayan Pourvatan
  • 11,898
  • 4
  • 42
  • 63
  • which android version your device running? – Hardik Nov 03 '13 at 07:15
  • 4.1.2 , but i run http://www.androidhive.info/2011/09/how-to-create-android-menus/ and its worked fine – Shayan Pourvatan Nov 03 '13 at 07:16
  • 2
    this is definitely one of the most frustrating problems with Android. I have no idea why it doesn't work. Their documentation does exactly what you're doing, yet it doesn't work. – Michael Yaworski Nov 03 '13 at 07:27
  • 1
    hello in androidhive demo it showed lower version than 3.0 if you run your program in 3.0 lower version 2.2,2.3 etc it will work – Hardik Nov 03 '13 at 07:30
  • 2
    http://developer.android.com/reference/android/view/Menu.html says that icons are not supported or something – Michael Yaworski Nov 03 '13 at 07:30
  • Possible duplicate of [How To show icons in Overflow menu in ActionBar](http://stackoverflow.com/questions/18374183/how-to-show-icons-in-overflow-menu-in-actionbar) – Fattie Aug 21 '16 at 14:14

11 Answers11

47

After Long try i found below solution which might help others to save there time. Basically, the solution provided by "lbarbosa", i like to thanks to him sincerely.

Tried this based on the previous answers and it works fine, at least with more recent versions of the support library (25.1):

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);

    if(menu instanceof MenuBuilder){
        MenuBuilder m = (MenuBuilder) menu;
        m.setOptionalIconsVisible(true);
    }

    return true;
}
Pranob
  • 641
  • 6
  • 11
37

If you're running your code on Android 3.0+, the icons in the menu are not shown by design. This is a design decision by Google.

You can read more about it in this on Android developers blog.

Szymon
  • 42,577
  • 16
  • 96
  • 114
28

No matter what design choices where made by the system, you can circumvent this with the solution provided in the top upvoted answer to this question

Code below for completeness. Tested working on android.support.v7.app.ActionBarActivity

@Override
public boolean onMenuOpened(int featureId, Menu menu)
{
    if(featureId == Window.FEATURE_ACTION_BAR && menu != null){
        if(menu.getClass().getSimpleName().equals("MenuBuilder")){
            try{
                Method m = menu.getClass().getDeclaredMethod(
                    "setOptionalIconsVisible", Boolean.TYPE);
                m.setAccessible(true);
                m.invoke(menu, true);
            }
            catch(NoSuchMethodException e){
                Log.e(TAG, "onMenuOpened", e);
            }
            catch(Exception e){
                throw new RuntimeException(e);
            }
        }
    }
    return super.onMenuOpened(featureId, menu);
}
Community
  • 1
  • 1
leRobot
  • 1,497
  • 1
  • 18
  • 30
  • 1
    This ALMOST worked for me. For reasons I do not understand, the featureId value was 0 for me. I replaced the first if statement with "if(featureId == Window.FEATURE_OPTIONS_PANEL && menu != null){" and it worked. Although, I am not sure that "FEATURE_OPTION_PANEL" is the correct meaning of the 0 my app is getting. – Steve Gelman Apr 20 '14 at 15:03
  • Well, most Java workarounds for Android's infamous embedded "best-practices" (a.k.a. pull an Apple on the developer API) rely on either Java reflection or outright source copypasta to project (which is by far less appealing, yet safer). Case in point, using the former people feel the need to over-condition the change. In this case, it was arbitrated that the adjustments were specific to for ActionBar calls, but there might be other valid such as yours, depending on API level and whatnot – leRobot Apr 21 '14 at 16:33
  • 3
    Since my featureId is 108 not 8, can I replace the `featureId == Window.FEATURE_ACTION_BAR` -> `(featureId & Window.FEATURE_ACTION_BAR) == Window.FEATURE_ACTION_BAR` – Ninja Nov 21 '15 at 12:47
  • 1
    don't really get the single ampersand (&) usage there, but as I said before anyways, you can attempt this onMenuOpened override on any activity, even without the first if() that checks if the feature exists (you can still check for menu != null of course), and see if behavior is desirable across devices/SDKs in your case.+ – leRobot Nov 23 '15 at 10:04
  • Thank you! I used your code, but replaced featureId == Window.FEATURE_ACTION_BAR with (featureId & Window.FEATURE_ACTION_BAR) == Window.FEATURE_ACTION_BAR. @leRobot: http://stackoverflow.com/questions/4757447/understanding-the-behavior-of-a-single-ampersand-operator-on-integers explains how and why the ampersand works and once you read that, you'll agree that the usage here is very smart :) – Igor Feb 01 '16 at 01:29
  • ah thx. Kinda low level notation for Java IMHO, but yeah, logic seems sound – leRobot Feb 01 '16 at 11:36
  • Great, it works, just have a question, if I just check if(menu != null), what will the problem? – Abhijit Nov 30 '16 at 13:11
  • I believe you might get unexpected behavior for other scenarios where onMenuOpen gets triggered but you don't have an action bar. For example, you might get the NoSuchMethodException. Basically, if your activity has an action bar there should be no problem, but check here for reference: https://developer.android.com/reference/android/view/Window.html – leRobot Dec 04 '16 at 09:46
19

Old question but hope it will help someone.

use the following code:

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

<item android:id="@+id/menu_item_share"
    android:title="Share"
    app:showAsAction="always"
    android:icon="@drawable/share" /></menu>

note i used app:showAsAction instead of android:showAsAction

Hamza Zaidi
  • 401
  • 7
  • 15
6

You can add to your XML file the attribute android:showAsAction="always" inside your item element. It then will show the relevant menu option as an icon inside your action bar.

Note that it will be instead of the text in the menu.

For further read, look here under android:showAsAction.

limlim
  • 3,115
  • 2
  • 34
  • 46
4
/* menu code */   
    <?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/one" android:title="one"
            android:icon="@mipmap/ic_launcher" app:showAsAction="always" />
        <item android:id="@+id/two" android:title="two"
            android:icon="@mipmap/ic_launcher" app:showAsAction="always" />
        <item android:id="@+id/three" android:title="three"
            android:icon="@mipmap/ic_launcher"  />
    </menu>
   /* Java code */

    @SuppressLint("RestrictedApi")
        @Override
        public boolean onCreateOptionsMenu(Menu menu)
        {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.mymenu,menu);
            if(menu instanceof MenuBuilder){
                MenuBuilder m = (MenuBuilder) menu;
                m.setOptionalIconsVisible(true);
            }
            return true;
        }
1

Forget all those, do this step. add app:showsAsAction="always" to your item. If you use android:showsAsAction="always" you won't get the solution. Try with adding app attribute to your item.

Vishnu gondlekar
  • 3,896
  • 21
  • 35
Subbu
  • 27
  • 1
1

I put explicit icons in onCreateOptionsMenu method using below code

for (int i = 0; i < menu.size(); i++) { MenuItem item = menu.getItem(i);

        if (item.getItemId() == R.id.print) {
            item.setIcon(getDrawable(R.drawable.print));

} }

0

Working with android.support.v7.app.AppCompatActivity, is making the input for the icons a very difficult task. You need to implement onMenuOpen, super method from AppComactActivity class. After this check, if the menu is not null. If the menu is not null pass Method class like this and setOptionalIconsVisible to true with boolean.

@Override
public boolean onMenuOpened(int featureId, Menu menu) {

    if(menu != null){
        if(menu.getClass().getSimpleName().equals("MenuBuilder")){
            try{
                Method m = menu.getClass().getDeclaredMethod(
                        "setOptionalIconsVisible", Boolean.TYPE);
                m.setAccessible(true);
                m.invoke(menu, true);
            }
            catch(NoSuchMethodException e){
                Log.e("MAIN", "onMenuOpened", e);
            }
            catch(Exception e){
                throw new RuntimeException(e);
            }
        }
    }
    return super.onMenuOpened(featureId, menu);
}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
0

Just add this attr inside item tag in your menu.xml

app:showAsAction="always
Mahmoud Abu Alheja
  • 3,343
  • 2
  • 24
  • 41
-2
@Override
public boolean onCreateOptionsMenu(Menu menu) {
  menu.add(0, 0, 0, "androidDemo").setIcon(R.drawable.ic_launcher);
  getMenuInflater().inflate(R.layout.menu, menu);
  return true;
}

and in xml:

 <item android:id="@+id/menuUpdate"
  android:icon="@drawable/update_icon"
  android:title="@string/Update" 
  android:showAsAction="always"/>

Vaishali Sutariya
  • 5,093
  • 30
  • 32