我想在菜单对象外面 onCreateOptionsMenu
方法中膨胀(这意味着当用户没有按下按钮时创建/显示菜单),所以我需要创建一个菜单实例将其传递给inflate方法。
这是我想要实现的一个例子:
Menu menu = // How to create an instance !?
new MenuInflater(context).inflate(R.menu.my_menu, menu)
菜单是一个界面,所以我需要知道哪个类正在实现它。我确实浏览了Android代码以获取有关如何创建Menu对象的任何提示,但仍无法找到我要查找的内容。
修改1
我的目标是从自定义视图中触发onOptionsItemSelected(MenuItem item)
事件,该事件将由活动处理,因此我需要一个具有特定itemId和title的MenuItem对象以将其传递给事件。
如果我可以成功创建一个Menu对象,那么很容易获得它的子MenuItems。
修改2
我不尝试显示菜单,我想要的是使用菜单XML中定义的元素填充ListView 具有title,icon和itemId,每当单击ListViewItem时,我想触发在我的活动中处理的onOptionsItemSelected(MenuItem item)
事件。
我知道我可以解析菜单XML以提取项目信息,但是如果不创建标准 MenuItem对象以将其作为参数传递,我将无法触发onOptionsItemSelected(MenuItem item)
。
任何帮助将不胜感激。谢谢!
答案 0 :(得分:41)
这是获取菜单实例的技巧:
PopupMenu p = new PopupMenu(getContext(), null);
Menu menu = p.getMenu();
答案 1 :(得分:28)
我找到了两个以编程方式创建Menu实例并对其进行充气的解决方案:
使用ActionbarSherlock库或AppCompat v7 library Menu menu = new MenuBuilder(context);
,您也可以编写自己的MenuBuilder
类
使用标准的Android SDK:
//通过反射创建实例
Menu menu = newMenuInstance(context);
protected Menu newMenuInstance(Context context) {
try {
Class<?> menuBuilderClass = Class.forName("com.android.internal.view.menu.MenuBuilder");
Constructor<?> constructor = menuBuilderClass.getDeclaredConstructor(Context.class);
return (Menu) constructor.newInstance(context);
} catch (Exception e) {e.printStackTrace();}
return null;
}
有了菜单实例后,您可以轻松地从程序中的菜单XML资源任何地方中对其进行充气
new MenuInflater(context).inflate(menuId, menu);
我测试了两种方法并且它们运行良好,我建议使用第二种方法,使用android SDK 中的标准Menu
和MenuItem
类,即使您的活动扩展了SherlockActivity 因为无论你使用onOptionsItemSelected(MenuItem item)
还是android.view.MenuItem
com.actionbarsherlock.view.MenuItem
答案 2 :(得分:2)
您无需对充气机进行任何操作即可添加自己的菜单。只需覆盖onCreateOptionsMenu
并开始在菜单对象中添加自己的项即可。例如:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, 1, Menu.NONE, "First");
menu.add(0, 2, Menu.NONE, "Second");
// repeat this to add additional menus
return true;
}
添加方法中的第二个参数是id
。使用唯一的 ids 标识您选择的菜单项。
答案 3 :(得分:1)
我不确定为什么这还不是答案,我知道这是一个老问题,但对于将来的读者来说。
如果您只是这样做:
val menu = MenuBuilder(context)
MenuInflater(context).inflate(R.menu.menu_XXXX, menu)
MenuBuilder
最终扩展了android.view.Menu
。经检查,这就是PopupMenu
的全部工作。
fun Context.inflateMenu(@MenuRes menuRes: Int): Lazy<MenuBuilder> = lazy {
MenuBuilder(this)
.also { MenuInflater(this).inflate(menuRes, it) }
}
fun Fragment.inflateMenu(@MenuRes menuRes: Int): Lazy<MenuBuilder> = lazy {
MenuBuilder(context)
.also { MenuInflater(context).inflate(menuRes, it) }
}
class MyActivity : AppCompatActivity(R.layout.activity_my) {
val menu by inflateMenu(R.menu.menu_my)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
}
}
class MyFragment : Fragment(R.layout.fragment_my) {
val menu by inflateMenu(R.menu.menu_my)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
}
}
答案 4 :(得分:0)
您可以拉出存储在PhoneWindow中的MenuBuilder(实现Menu界面)的实例,该实例正在Activity中使用。我有一个有效的解决方案,它使用Java Reflection。
我创建了一个项目“InDroid”,以揭示几个重要的隐藏方法,来自Android平台的变量 - http://code.google.com/p/indroid/
BR, Prasanta