PopupMenu:弹出菜单
PopupMenu弹出菜单,在点击控件的位置附件弹出一个菜单给用户选择。根据所点View位置会自动适应调整弹出菜单的位置,比如下方空间不够,就会将菜单在View的上方弹出。

1、定义Menu菜单文件
可以代码定义,也可以在在src/main/res/menu/菜单文件夹下定义菜单xml文件。这里选择后者,方便。注意:菜单项必要有title标题

关于<menu />标签的语法详见 Guides > Menu resource">Android Developers > Guides > Menu resource。
1.1、菜单group
增加菜单组,将功能相近的菜单放在一个group节点中
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
...
<group android:id="@+id/two">
<item
android:id="@+id/close"
android:icon="@drawable/close"
android:title="关闭" />
...
</group>
</menu>1.2、子菜单(item > menu)
可以在item层级下面继续定义menu节点,也就是子菜单。比如:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
...
<item
android:id="@+id/open"
android:icon="@drawable/open"
android:title="打开">
<menu>
<item
android:id="@+id/choose"
android:title="选择" />
<item
android:id="@+id/recent"
android:title="最近" />
</menu>
</item>
...
</menu>效果就是“打开”菜单选项下面还有二级菜单可打开

2、创建PopupMenu
创建一个PopupMenu很简单,只需要下面几步:
2.1、PopupMenu基本操作
①创建PopupMenu对象
PopupMenu popupMenu = new PopupMenu(this, view);②加载xml菜单初始化菜单项
popupMenu.getMenuInflater().inflate(R.menu.pop_menu, popupMenu.getMenu());③设置PopupMenu菜单的点击事件:通过MenuItem(这是个interface接口)的id判断点击哪个菜单项从而执行具体的操作。
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
return true;
}
});④显示PopupMenu菜单
popupMenu.show();2.2、PopupMenu菜单项动态变化
有时候点击不同的View需要显示不同的菜单项,这时候可以隐藏不需要的MenuItem:
...
popupMenu.getMenu().findItem(R.id.file).setVisible(false);
...2.3、PopupMenu显示icon
虽然在写菜单xml文件的时候给Item加上了icon也就是菜单图标:
...
<item
android:id="@+id/file"
android:icon="@drawable/folder"
android:title="文件" />
...但是实际并没有显示,经过查找资料发现,在Android 4.0以上默认不再显示Menu的图标,只显示标题。方法还是有的:
①对于API level 29及以上,Android又重新加入了一个setForceShowIcon()方法提供给开发者,用来设置icon是否显示
popupMenu.setForceShowIcon(true);
...注意:Call requires API level 29 (current min is 24): android.widget.PopupMenu#setForceShowIcon
②通过反射,让PopupMenu对象显示icon
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 (Exception e) {
e.printStackTrace();
}
相关阅读:

