Android 上带有图标的弹出菜单
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20836385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Popup menu with icon on Android
提问by Kuldeep
My menu xml code menu.xml:
我的菜单 xml 代码menu.xml:
<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Single menu item
Set id, icon and Title for each menu item
-->
<item android:id="@+id/back"
android:icon="@drawable/back1"
android:showAsAction="never"
android:title="Back" />
<item android:id="@+id/My_Profile"
android:icon="@drawable/myprofile"
android:showAsAction="never"
android:title="My Profile" />
<item android:id="@+id/Job_Alert"
android:icon="@drawable/jobalert4"
android:showAsAction="never"
android:title="Job Alert !" />
<item android:id="@+id/saved_job"
android:icon="@drawable/jobapplied"
android:title="Saved Jobs"
/>
<item android:id="@+id/Logout"
android:icon="@drawable/logout"
android:title="Logout" />
</menu>
I am calling menu xml like this
我正在像这样调用菜单 xml
PopupMenu popup = new PopupMenu(getBaseContext(), v);
popup.getMenuInflater().inflate(R.menu.menu, popup.getMenu());
popup.show();
But it does not show the icon.
但它不显示图标。
How can I set the icon on the popup menu?
如何在弹出菜单上设置图标?
采纳答案by GrIsHu
Actually Context Menudoes not support the icons.
实际上上下文菜单不支持图标。
If you want context menu/pop up menu with icons Hereis the way.
如果你想要带有图标的上下文菜单/弹出菜单这是方法。
You can go for QuickAction3Dwhich servers the functionality which you want.
您可以选择QuickAction3D,它可以提供您想要的功能。
Check out threadwhich might help you.
查看可能对您有帮助的线程。
回答by Ajay Sivan
You can create popup menu with icon using the MenuBuilder
and MenuPopupHelper
.
您可以使用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) {}
});
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>
回答by Bao Le
You can enable icons for popup menu by using Java reflection to call a hidden method as below:
您可以通过使用 Java 反射调用隐藏方法来启用弹出菜单的图标,如下所示:
public static void setForceShowIcon(PopupMenu popupMenu) {
try {
Field[] fields = popupMenu.getClass().getDeclaredFields();
for (Field field : fields) {
if ("mPopup".equals(field.getName())) {
field.setAccessible(true);
Object menuPopupHelper = field.get(popupMenu);
Class<?> classPopupHelper = Class.forName(menuPopupHelper
.getClass().getName());
Method setForceIcons = classPopupHelper.getMethod(
"setForceShowIcon", boolean.class);
setForceIcons.invoke(menuPopupHelper, true);
break;
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
回答by René AD
You could use reflection as described here: https://stackoverflow.com/a/18431605/4521603
您可以按照此处所述使用反射:https: //stackoverflow.com/a/18431605/4521603
Or if you use Xamarin / C#:
或者,如果您使用 Xamarin / C#:
add:
添加:
using Java.Lang.Reflect;
Then use this in your code:
然后在您的代码中使用它:
PopupMenu puMenu = new PopupMenu(Activity, v)
Field field = puMenu.Class.GetDeclaredField("mPopup");
field.Accessible = true;
Java.Lang.Object menuPopupHelper = field.Get(puMenu);
Method setForceIcons = menuPopupHelper.Class.GetDeclaredMethod("setForceShowIcon", Java.Lang.Boolean.Type);
setForceIcons.Invoke(menuPopupHelper, true);
puMenu.Inflate (Resource.Menu.your_actions);
puMenu.Show ();
回答by Cícero Moura
Use this:
用这个:
/**
* Copied from android.support.v7.widget.PopupMenu.
* "mPopup.setForceShowIcon(true);" in the constructor does the trick :)
*
* @author maikvlcek
* @since 5:00 PM - 1/27/14
*/
public class IconizedMenu implements MenuBuilder.Callback, MenuPresenter.Callback {
private Context mContext;
private MenuBuilder mMenu;
private View mAnchor;
private MenuPopupHelper mPopup;
private OnMenuItemClickListener mMenuItemClickListener;
private OnDismissListener mDismissListener;
/**
* Callback interface used to notify the application that the menu has closed.
*/
public interface OnDismissListener {
/**
* Called when the associated menu has been dismissed.
*
* @param menu The PopupMenu that was dismissed.
*/
public void onDismiss(IconizedMenu menu);
}
/**
* Construct a new PopupMenu.
*
* @param context Context for the PopupMenu.
* @param anchor Anchor view for this popup. The popup will appear below the anchor if there
* is room, or above it if there is not.
*/
public IconizedMenu(Context context, View anchor) {
mContext = context;
mMenu = new MenuBuilder(context);
mMenu.setCallback(this);
mAnchor = anchor;
mPopup = new MenuPopupHelper(context, mMenu, anchor);
mPopup.setCallback(this);
mPopup.setForceShowIcon(true);
}
/**
* @return the {@link android.view.Menu} associated with this popup. Populate the returned Menu with
* items before calling {@link #show()}.
*
* @see #show()
* @see #getMenuInflater()
*/
public Menu getMenu() {
return mMenu;
}
/**
* @return a {@link android.view.MenuInflater} that can be used to inflate menu items from XML into the
* menu returned by {@link #getMenu()}.
*
* @see #getMenu()
*/
public MenuInflater getMenuInflater() {
return new SupportMenuInflater(mContext);
}
/**
* Inflate a menu resource into this PopupMenu. This is equivalent to calling
* popupMenu.getMenuInflater().inflate(menuRes, popupMenu.getMenu()).
* @param menuRes Menu resource to inflate
*/
public void inflate(int menuRes) {
getMenuInflater().inflate(menuRes, mMenu);
}
/**
* Show the menu popup anchored to the view specified during construction.
* @see #dismiss()
*/
public void show() {
mPopup.show();
}
/**
* Dismiss the menu popup.
* @see #show()
*/
public void dismiss() {
mPopup.dismiss();
}
/**
* Set a listener that will be notified when the user selects an item from the menu.
*
* @param listener Listener to notify
*/
public void setOnMenuItemClickListener(OnMenuItemClickListener listener) {
mMenuItemClickListener = listener;
}
/**
* Set a listener that will be notified when this menu is dismissed.
*
* @param listener Listener to notify
*/
public void setOnDismissListener(OnDismissListener listener) {
mDismissListener = listener;
}
/**
* @hide
*/
public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
if (mMenuItemClickListener != null) {
return mMenuItemClickListener.onMenuItemClick(item);
}
return false;
}
/**
* @hide
*/
public void onCloseMenu(MenuBuilder menu, boolean allMenusAreClosing) {
if (mDismissListener != null) {
mDismissListener.onDismiss(this);
}
}
/**
* @hide
*/
public boolean onOpenSubMenu(MenuBuilder subMenu) {
if (subMenu == null) return false;
if (!subMenu.hasVisibleItems()) {
return true;
}
// Current menu will be dismissed by the normal helper, submenu will be shown in its place.
new MenuPopupHelper(mContext, subMenu, mAnchor).show();
return true;
}
/**
* @hide
*/
public void onCloseSubMenu(SubMenuBuilder menu) {
}
/**
* @hide
*/
public void onMenuModeChange(MenuBuilder menu) {
}
/**
* Interface responsible for receiving menu item click events if the items themselves
* do not have individual item click listeners.
*/
public interface OnMenuItemClickListener {
/**
* This method will be invoked when a menu item is clicked if the item itself did
* not already handle the event.
*
* @param item {@link MenuItem} that was clicked
* @return <code>true</code> if the event was handled, <code>false</code> otherwise.
*/
public boolean onMenuItemClick(MenuItem item);
}
}
回答by Gil Snovsky
before popupMenu.show(); use
在 popupMenu.show() 之前;用
try {
Field mFieldPopup=popupMenu.getClass().getDeclaredField("mPopup");
mFieldPopup.setAccessible(true);
MenuPopupHelper mPopup = (MenuPopupHelper) mFieldPopup.get(popupMenu);
mPopup.setForceShowIcon(true);
} catch (Exception e) {
}
回答by Mohamed Ayed
You can implement this By the use of Reflection if u don`t familiar with it with the help of this awesome java advanced feature u can modify the runtime behavior of applications running in the JVM you can look at the object and perform its methods on runtime and in our case we need to modify popupMenu behavior at runtime instead of extend the core class and modify it ;) hope that help Try my method working like a charm
您可以通过使用反射来实现这一点,如果您不熟悉它,借助这个很棒的 Java 高级功能,您可以修改在 JVM 中运行的应用程序的运行时行为,您可以查看对象并在运行时执行其方法在我们的例子中,我们需要在运行时修改 popupMenu 行为,而不是扩展核心类并修改它;) 希望有所帮助 尝试我的方法像魅力一样工作
private void showPopupMenu(View view) {
// inflate menu
PopupMenu popup = new PopupMenu(mcontext, view);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.main, popup.getMenu());
Object menuHelper;
Class[] argTypes;
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popup);
argTypes = new Class[]{boolean.class};
menuHelper.getClass().getDeclaredMethod("setForceShowIcon", argTypes).invoke(menuHelper, true);
} catch (Exception e) {
}
popup.show();
}
回答by Rakeeb Rajbhandari
It's because when you use the showAsAction="never"
attribute, the default overflow does not return your icon. You could create your own overflowlike this:
这是因为当您使用该showAsAction="never"
属性时,默认溢出不会返回您的图标。您可以像这样创建自己的溢出:
<item android:title=""
android:id="@+id/overflow"
android:showAsAction="always"
android:icon="@drawable/overflow_icon">
<menu >
<item android:id="@+id/back"
android:icon="@drawable/back1"
android:title="Back" />
<item android:id="@+id/My_Profile"
android:icon="@drawable/myprofile"
android:title="My Profile" />
<item android:id="@+id/Job_Alert"
android:icon="@drawable/jobalert4"
android:title="Job Alert !" />
<item android:id="@+id/saved_job"
android:icon="@drawable/jobapplied"
android:title="Saved Job"/>
<item android:id="@+id/Logout"
android:icon="@drawable/logout"
android:title="Logout" />
</menu>
</item>
回答by Sush
if trying this code in any activity then replace getbBaseContext() with this i.e activity context
如果在任何活动中尝试此代码,则将 getbBaseContext() 替换为此活动上下文
PopupMenu popup = new PopupMenu(this, v);