Можно ли отображать значки в PopupMenu?

Мне очень нравится новый PopupMenu, который мы получили в версии 3.0, но я просто не могу отображать какие-либо значки рядом с элементами меню в нем. Я раздуваю меню из .xml ниже:

<item android:id="@+id/menu_delete_product" android:icon="@drawable/sym_action_add" android:title="delete" android:showAsAction="ifRoom|withText" /> <item android:id="@+id/menu_modify_product" android:icon="@drawable/sym_action_add" android:title="modify" android:showAsAction="ifRoom|withText" /> <item android:id="@+id/menu_product_details" android:icon="@drawable/sym_action_add" android:title="details" android:showAsAction="ifRoom|withText" /> 

С помощью этого кода:

 image.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { PopupMenu pop = new PopupMenu(getActivity(), v); pop.getMenuInflater().inflate(R.menu.shelves_details_menu, pop.getMenu()); pop.show(); } }); 

Я не могу заставить значки появляться, я что-то упускаю?

Solutions Collecting From Web of "Можно ли отображать значки в PopupMenu?"

Если вы хотите быть немного авантюрным, посмотрите на исходный код Google для PopupMenu. Создайте свой собственный класс, т.е. MyPopupMenu, который совпадает с классом PopupMenu Google, но сделайте небольшое изменение.

В конструкторе PopupMenu:

 public MyPopupMenu(Context context, View anchor) { // TODO Theme? mContext = context; mMenu = new MenuBuilder(context); mMenu.setCallback(this); mAnchor = anchor; mPopup = new MenuPopupHelper(context, mMenu, anchor); mPopup.setCallback(this); mPopup.setForceShowIcon(true); //ADD THIS LINE } 

Используйте метод setForceShowIcon, чтобы заставить его показать значок. Вы также можете просто открыть общедоступный метод для установки этого флага, в зависимости от ваших потребностей.

Вклад в решение, предоставленное Гаэном Болгером. Используйте этот код, если вы получите «IllegalAccessException: доступ к полю не разрешен».

 PopupMenu popup = new PopupMenu(mContext, view); 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(); } prepareMenu(popup.getMenu()); popup.show(); 

текст

Я смог показать значки, используя отражение. Это может быть не самое элегантное решение, но оно работает.

  try { Class<?> classPopupMenu = Class.forName(popupMenu .getClass().getName()); Field mPopup = classPopupMenu.getDeclaredField("mPopup"); mPopup.setAccessible(true); Object menuPopupHelper = mPopup.get(popupMenu); Class<?> classPopupHelper = Class.forName(menuPopupHelper .getClass().getName()); Method setForceIcons = classPopupHelper.getMethod( "setForceShowIcon", boolean.class); setForceIcons.invoke(menuPopupHelper, true); } catch (Exception e) { e.printStackTrace(); } 

Мы можем использовать модель подменю. Таким образом, нам не нужно писать метод отображения всплывающего меню, он будет отображаться автоматически. Взгляни:

menu.xml

 <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/action_more" android:icon="@android:drawable/ic_menu_more" android:orderInCategory="1" android:showAsAction="always" android:title="More"> <menu> <item android:id="@+id/action_one" android:icon="@android:drawable/ic_popup_sync" android:title="Sync"/> <item android:id="@+id/action_two" android:icon="@android:drawable/ic_dialog_info" android:title="About"/> </menu> </item> </menu> 

В MainActivity.java

 @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } 

Результат:

результат

Перед использованием метода popup.show () создать экземпляр MenuPopupHelper и вызвать метод setForceShowIcon (true), например

  try { Field mFieldPopup=popupMenu.getClass().getDeclaredField("mPopup"); mFieldPopup.setAccessible(true); MenuPopupHelper mPopup = (MenuPopupHelper) mFieldPopup.get(popupMenu); mPopup.setForceShowIcon(true); } catch (Exception e) { } 

Самый простой способ найти это – использовать MenuBuilder и MenuPopupHelper .

 MenuBuilder menuBuilder =new MenuBuilder(this); MenuInflater inflater = new MenuInflater(this); inflater.inflate(R.menu.menu, menuBuilder); MenuPopupHelper optionsMenu = new MenuPopupHelper(this, menuBuilder, view); optionsMenu.setForceShowIcon(true); // Set Item Click Listener menuBuilder.setCallback(new MenuBuilder.Callback() { @Override public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { switch (item.getItemId()) { case R.id.opt1: // Handle option1 Click return true; case R.id.opt2: // Handle option2 Click return true; default: return false; } } @Override public void onMenuModeChange(MenuBuilder menu) {} }); // Display the menu optionsMenu.show(); 

menu.xml

 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/opt1" android:icon="@mipmap/ic_launcher" android:title="option 1" /> <item android:id="@+id/opt2" android:icon="@mipmap/ic_launcher" android:title="option 2" /> </menu> 

Введите описание изображения здесь

Я нашел для этого свое собственное решение, используя MenuPopupHelper.setForceShowIcon(true) .

 private void createMenu(int menuRes, View anchor, MenuBuilder.Callback callback) { Context context = anchor.getContext(); NavigationMenu navigationMenu = new NavigationMenu(context); navigationMenu.setCallback(callback); SupportMenuInflater supportMenuInflater = new SupportMenuInflater(context); supportMenuInflater.inflate(menuRes, navigationMenu); MenuPopupHelper menuPopupHelper = new MenuPopupHelper(context, navigationMenu, anchor); menuPopupHelper.setForceShowIcon(true); menuPopupHelper.show(); } 

Применение

 private void initMenu(View view) { view.findViewById(R.id.myButton).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { createMenu(R.menu.help_menu, view, new MenuBuilder.Callback() { @Override public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { switch (item.getItemId()) { case R.id.id1: // Do something break; case R.id.id2: // Do something break; case R.id.id3: // Do something break; } return true; } @Override public void onMenuModeChange(MenuBuilder menu) { } }); } }); } 

PopupMenu не будет отображать значки. Вы можете использовать ActionBar.

http://developer.android.com/guide/topics/ui/actionbar.html

Некоторые из вышеперечисленных решений будут работать с рефлекторным взломом,

Просто поделитесь этим: недавно я столкнулся с теми же проблемами, но я также хотел создать более настраиваемую вещь (добавление пользовательского представления в меню), поэтому я создал следующую библиотеку.

https://github.com/shehabic/Droppy