Reputation: 12940
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.
I also need the device "menu" button to show the same menu.
Upvotes: 12
Views: 15432
Reputation: 81
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()
}
Upvotes: 7
Reputation: 1
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();
Upvotes: 0
Reputation: 1
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();
}
Upvotes: 0
Reputation: 847
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()
.
Upvotes: 12
Reputation: 1574
Try this
MenuPopupHelper menuHelper = new MenuPopupHelper(getContext(), (MenuBuilder)
popupmenu.getMenu(), button);
menuHelper.setForceShowIcon(true);
menuHelper.show();
Worked for me.
Upvotes: 2
Reputation: 3889
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>
Upvotes: 4
Reputation: 12940
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.
Upvotes: 3
Reputation: 2423
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:
=>
Upvotes: 5