是否可以在PopupMenu中显示图标?

我非常喜欢3.0版本中的新PopupMenu,但是我不能在菜单项旁边显示任何图标。 我正在从下面的.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(); } }); 

我不能让图标出现,我错过了什么?

如果你愿意冒险,可以看看Google的PopupMenu源代码。 创build自己的类,即MyPopupMenu,这是谷歌的PopupMenu类相同,但做一个小的改变。

在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强制它显示图标。 你也可以根据你的需要公开一个公共方法来设置这个标志。

对Gaelan Bolger提供的解决scheme的贡献。 如果出现“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(); 

文本

我能够使用reflection显示图标。 它可能不是最优雅的解决scheme,但它的工作原理。

  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(); } 

我们可以使用子菜单模式。 所以我们不需要编写显示popup菜单的方法,它会自动显示。 看一看:

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) { } 

我发现最简单的方法是使用MenuBuilderMenuPopupHelper

 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> 

在这里输入图像描述

我find了一个本地解决scheme,使用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

上面的一些解决scheme将与反思黑客工作,

只是分享一下:我最近遇到了同样的问题,但我也想创build一个更加自定义的东西(在菜单中添加自定义视图),所以我创build了下面的lib。

https://github.com/shehabic/Droppy