Android Toolbar Popup menu not showing icons

14.7k views Asked by At

I am trying to show a drop down menu for my toolbar which includes BOTH text and icons:

<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"
        android:title="@string/menu.add"
        android:icon="@drawable/ic_add_black_24dp"
        app:showAsAction="always" />

    <item
        android:id="@+id/menu_edit"
        android:title="@string/menu.edit"
        android:icon="@drawable/ic_create_black_24dp"
        app:showAsAction="never" />

</menu>

The menu_add does show with the icon on the toolbar itself but the menu_edit only shows the text without the icon.

This answer: https://stackoverflow.com/a/19750717/197127 says that Google has removed it by design but does not refer to how you may override it.

Edit

I also need the device "menu" button to show the same menu.

8

There are 8 answers

0
checklist On BEST ANSWER

I found this solution: https://stackoverflow.com/a/30337653/197127. Basically, overriding a method and it does not break the device menu button or the overflow. Thanks to all.

7
Harin On

Yes, its not being displayed in new versions of support library, but you can do the trick by adding submenu. (You can add it via both xml and code). like this:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_settings"
        android:icon="@drawable/abc_ic_menu_moreoverflow_mtrl_alpha"
        android:title="@string/action_settings"
        app:showAsAction="always">
        <menu>
            <item
                android:icon="@drawable/ic_event"
                android:title="@string/action_settings"
                app:showAsAction="always" />
            <item
                android:icon="@drawable/ic_event"
                android:title="@string/action_settings"
                app:showAsAction="always" />
        </menu>
    </item>
</menu>

Hope it helped:) Edit: see snapshots of above code:

menu => menu open

1
Satish Singh On

This Kotlin code worked for me. I used "popup.setForceShowIcon(true)"

val popup = PopupMenu(context, button);

popup.menuInflater.inflate(menuRes, popup.menu);

popup.setForceShowIcon(true)

The full code is written below

//R.menu.menu_popup -- Menu xml File
<menu
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_1"
        android:icon="@drawable/email"
        android:title="Email" />
    <item android:id="@+id/menu_2"
        android:icon="@drawable/phone"
        android:title="Phone" />
</menu>

// Inside Activity
findViewById<Button>(R.id.button1).setOnClickListener {
    show_PopUp_Menu(this, it, R.menu.menu_popup)
}


@SuppressLint("RestrictedApi")
fun show_PopUp_Menu(context: Context, button:Button, menuRes: Int) {

    val popup = PopupMenu(context, button)
    popup.menuInflater.inflate(menuRes, popup.menu)

    popup.setOnMenuItemClickListener { menuItem: MenuItem ->
        when(menuItem.itemId){
            R.id.menu_1->{
                Toast.makeText(this, "Menu 1 clicked", Toast.LENGTH_SHORT).show()
                true
            }
            R.id.menu_2->{
                Toast.makeText(this, "Menu 2 clicked", Toast.LENGTH_SHORT).show()
                true
            }
            else -> false
        }
    }
    
    popup.setOnDismissListener {
        // Respond to popup being dismissed.
    }
    popup.setForceShowIcon(true)
    popup.show()
}
0
Akshay Nirwal On

I created something like this: Try this:

    Menu menu= toolbar.getMenu();
    Method menuMethod = null;
    try {
       menuMethod = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
       menuMethod.setAccessible(true);
       menuMethod.invoke(menu, true);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }
0
yubaraj poudel On

It doesnot work on android support v7 version but you can tweak this by modifying little bit. below code works for me

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

<item
    android:id="@+id/action_settings"
    android:icon="@drawable/abc_ic_menu_moreoverflow_mtrl_alpha"
    android:title="@string/action_settings"
    app:showAsAction="always">
    <menu>

        <item
            android:id="@+id/action_rate"
            android:icon="@drawable/ic_grade_black_24dp"
            android:orderInCategory="100"
            android:title="@string/action_rate"
            app:showAsAction="never" />
        <item
            android:id="@+id/action_share"
            android:icon="@drawable/ic_share_black_24dp"
            android:orderInCategory="101"
            android:title="@string/action_share"
            app:showAsAction="never" />
        <item
            android:id="@+id/action_enquiry"
            android:icon="@drawable/ic_message_black_24dp"
            android:orderInCategory="102"
            android:title="@string/action_enquiry"
            app:showAsAction="never" />
        <item
            android:id="@+id/action_disclaimer"
            android:icon="@drawable/ic_info_black_24dp"
            android:orderInCategory="103"
            android:title="@string/action_disclaimer"
            app:showAsAction="never" />
    </menu>
</item>

0
Mazhar Ali On

From the Above 3.0 android icons in the pop menu are not displayed so you have to trick it and this works you can try

   //init the popup
   PopupMenu popup = new PopupMenu(context, anchor);
 
        /*  The below code in try catch is responsible to display icons*/
            try {
                Field[] fields = popup.getClass().getDeclaredFields();
                for (Field field : fields) {
                    if ("mPopup".equals(field.getName())) {
                        field.setAccessible(true);
                        Object menuPopupHelper = field.get(popup);
                        Class<?> classPopupHelper = Class.forName(menuPopupHelper.getClass().getName());
                        Method setForceIcons = classPopupHelper.getMethod("setForceShowIcon", boolean.class);
                        setForceIcons.invoke(menuPopupHelper, true);
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
 
        //inflate menu
        popup.getMenuInflater().inflate(R.menu.popup_menu, popup.getMenu());
 
        //show menu
        popup.show();
2
Kikju On

I created something like this:

@SuppressLint("RestrictedApi")
fun Menu.showIcons() {
    (this as? MenuBuilder)?.setOptionalIconsVisible(true)
}

and it works basically on any menu.

For toolbar, you can override onPrepareOptionsMenu in activity or fragment and before calling super just call menu.showIcons() or you can use it with PopupMenu like so PopupMenu(requireContext(), anchor).menu.showIcons().

1
Rahul sharma On

Try this

 MenuPopupHelper menuHelper = new MenuPopupHelper(getContext(), (MenuBuilder) 
 popupmenu.getMenu(), button);
 menuHelper.setForceShowIcon(true);
 menuHelper.show();

Worked for me.