是否可以在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) { }
我发现最简单的方法是使用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>
我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。
上面的一些解决scheme将与反思黑客工作,
只是分享一下:我最近遇到了同样的问题,但我也想创build一个更加自定义的东西(在菜单中添加自定义视图),所以我创build了下面的lib。