[英]Android: How to include a menu xml inside another menu xml?

Simple question.


I have my menu of child items:


<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="">

<!-- SNIP ---> 

And later I would want to include it as a submenu of this menu:


<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="" >

        android:title="Remove Player from Team">

        android:title="Assign Batting Position">

        android:title="Assign Feilding Position">
        <!-- I want to include the submenu here-->


The question here kind of answered this - I'm not sure how to inflate the submenu.

这里的问题有点回答 - 我不知道如何给子菜单充气。

I'm thinking that you inflate it in the onContextItemSelected method - but inflate requires a menu object, which isn't passed into onContextItemSelected.

我想你在onContextItemSelected方法中给它充气 - 但是inflate需要一个菜单​​对象,它不会传递给onContextItemSelected。

2 个解决方案



It's sadly not possible in plain XML, but there's a nice way without using manual Menu.add* methods: here's how you can obtain a Menu instance to include/inflate the other file into:

遗憾的是,在纯XML中不可能,但是没有使用手动Menu.add *方法有一个很好的方法:这里是如何获得一个Menu实例来包含/膨胀其他文件到:

inflater.inflate(, menu);
MenuItem fp_menu = menu.findItem(;
inflater.inflate(, fp_menu.getSubMenu()); // needs <menu />

You can put the above code to any of the following using the specified inflater:


  • Activity.onCreateContextMenu(menu, v, menuInfo): getMenuInflater()
  • Activity.onCreateContextMenu(menu,v,menuInfo):getMenuInflater()
  • Fragment.onCreateContextMenu(menu, v, menuInfo): getActivity().getMenuInflater()
  • Fragment.onCreateContextMenu(menu,v,menuInfo):getActivity()。getMenuInflater()
  • Activity.onCreateOptionsMenu(menu): getMenuInflater()
  • Activity.onCreateOptionsMenu(menu):getMenuInflater()
  • Fragment.onCreateOptionsMenu(menu, inflater): inflater
  • Fragment.onCreateOptionsMenu(menu,inflater):inflater


<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="">
    <item android:id="@+id/teameditor_remove"
          android:title="Remove Player from Team"
    <item android:id="@+id/teameditor_assignbattingposition"
          android:title="Assign Batting Position"
    <item android:id="@+id/teameditor_assignfieldingposition"
          android:title="Assign Feilding Position">
        <menu><!-- include: positions.xml --></menu>

The empty <menu /> placeholder is very important, without that getSubMenu() will be null!



<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="">
    <item android:id="@+id/fp_pitcher"
    <item android:id="@+id/fp_catcher"
    <!-- SNIP ---> 

Note on your onContextItemSelected idea

I'm thinking that you inflate it in the onContextItemSelected method [...]


I think it's too late if you're in onContextItemSelected, since you're already handling the event which would lead to showing you're submenu... which is not inflated yet. You could try the same inflate into getSubMenu(), but I'm not sure that it'll show up. It's best to create the menu where it's supposed to be created.


Note on including the same submenu multiple times in the same menu

Untested If you need to inflate the same positions.xml into teameditor_assignbattingposition as well you'll have some problems in onOptionsItemSelected/onContextItemSelected. One way to work around it is to convert the findItem variable to a field and save the reference to both

未经测试如果您需要将相同的positions.xml扩展到teameditor_assignbattingposition,那么在onOptionsItemSelected / onContextItemSelected中会遇到一些问题。解决此问题的一种方法是将findItem变量转换为字段并将引用保存到两者

this.fp_menu = menu.findItem(;
inflater.inflate(, fp_menu.getSubMenu());
this.bp_menu = menu.findItem(;
inflater.inflate(, bp_menu.getSubMenu());

and then in on*ItemSelected:

然后在* ItemSelected上:

switch (item.getItemId()) {
        if (item == fp_menu.findItem( {
            // selected inside teameditor_assignfieldingposition
        } else if (item == bp_menu.findItem( {
            // selected inside teameditor_assignbattingposition
        } else {
            throw new ImLostInMenusException();
        return true;
return super.on*ItemSelected();



It's not pretty, but if you you need to do it without copying the XML content over (which would work easily). When you inflate the second menu you can also do a menu.findItem( for each of the items you want to add. If you have the strings ("Pitcher" and "Catcher") in a String array resource you could iterate over that array to add the same items as in the original. Alternatively, you would probably need to parse the other menu's XML, you can cheat that by just inflating it I guess, and then using it's size() and getItem(int).


In fact, you could just inflate the first menu into a Menu and then use size() and getItem(int) to get the MenuItems out of it. Then, for each item you can do add(menuItem.getGroupId(), menuItem.getItemId(), menuItem.getOrder(), menuItem.getTitle()) on the getSubMenu() of the second menu's findItem( That should add all the items of the first menu as a submenu of that item. This means you are inflating two XML files, but it's kind of unavoidable if you want to use separate XML files, seeing as there isn't an <include> for menu XML files. I would probably inflate the second menu normally (in the onCreateOptionsMenu(...)) and then add the first menu as a submenu in the onPrepareOptionsMenu(...) (it's given the menu you created in onCreateOptionsMenu(...)). I think you could do it all in onCreateOptionsMenu(...), but I believe it's better practice to make modifications to the menu in onPrepareOptionsMenu(...).

实际上,您可以将第一个菜单膨胀到菜单中,然后使用size()和getItem(int)来获取MenuItems。然后,对于每个项目,你可以在第二个菜单的findItem(的getSubMenu()上添加(menuItem.getGroupId(),menuItem.getItemId(),menuItem.getOrder(),menuItem.getTitle())。 )。这应该将第一个菜单的所有项目添加为该项目的子菜单。这意味着你要膨胀两个XML文件,但如果你想使用单独的XML文件,那就不可避免了,因为菜单XML文件没有 。我可能会正常膨胀第二个菜单(在onCreateOptionsMenu(...)中)然后将第一个菜单添加为onPrepareOptionsMenu(...)中的子菜单(它给出了你在onCreateOptionsMenu(...)中创建的菜单) 。我认为你可以在onCreateOptionsMenu(...)中完成所有工作,但我相信最好在onPrepareOptionsMenu(...)中对菜单进行修改。

I think the second way is the best solution I can find, I'm leaving the first option as an alternative just in case.




© 2014-2018 粤ICP备14056181号