Android:如何在另一个菜单xml中包含菜单xml?

时间:2012-07-11 23:47:20

标签: android xml contextmenu submenu

简单的问题。

我有我的儿童用品菜单:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/fp_pitcher"
        android:title="Pitcher">
    </item>
    <item
        android:id="@+id/fp_catcher"
        android:title="Catcher">
    </item>
<!-- SNIP ---> 
</menu>

后来我想把它作为这个菜单的子菜单包含在内:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >


    <item
        android:id="@+id/teameditor_remove"
        android:title="Remove Player from Team">
    </item>

    <item
        android:id="@+id/teameditor_assignbattingposition"
        android:title="Assign Batting Position">
    </item>

    <item
        android:id="@+id/teameditor_assignfieldingposition"
        android:title="Assign Feilding Position">
        <!-- I want to include the submenu here-->
    </item>

</menu>

The question here有点回答 - 我不知道如何给子菜单充气。

我认为你在onContextItemSelected方法中膨胀它 - 但是膨胀需要一个菜单​​对象,它不会传递给onContextItemSelected。

2 个答案:

答案 0 :(得分:3)

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

inflater.inflate(R.menu.player, menu);
MenuItem fp_menu = menu.findItem(R.id.teameditor_assignfieldingposition);
inflater.inflate(R.menu.positions, fp_menu.getSubMenu()); // needs <menu />

您可以使用指定的inflater

将上述代码添加到以下任何代码中
  • Activity.onCreateContextMenu(menu, v, menuInfo)getMenuInflater()
  • Fragment.onCreateContextMenu(menu, v, menuInfo)getActivity().getMenuInflater()
  • Activity.onCreateOptionsMenu(menu)getMenuInflater()
  • Fragment.onCreateOptionsMenu(menu, inflater)inflater

菜单/ player.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/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>
    </item>
</menu>

空的<menu />占位符非常重要 ,而getSubMenu() null将不会<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/fp_pitcher" android:title="Pitcher" /> <item android:id="@+id/fp_catcher" android:title="Catcher" /> <!-- SNIP ---> </menu>

菜单/ positions.xml

onContextItemSelected

关于onContextItemSelected想法

的说明
  

我在想你用onContextItemSelected方法[...]

来夸大它

我认为如果你在getSubMenu()已经太晚了,因为你已经处理了这个事件,这会导致你显示你的子菜单......这还没有膨胀。你可以尝试同样的膨胀到positions.xml,但我不确定它会出现。最好创建一个应该创建它的菜单。

请注意在同一菜单中多次包含相同的子菜单

未经测试 如果您需要将同一teameditor_assignbattingposition充气到onOptionsItemSelected,那么onContextItemSelected会遇到一些问题/ findItem。 解决此问题的一种方法是将this.fp_menu = menu.findItem(R.id.teameditor_assignfieldingposition); inflater.inflate(R.menu.positions, fp_menu.getSubMenu()); this.bp_menu = menu.findItem(R.id.teameditor_assignbattingposition); inflater.inflate(R.menu.positions, bp_menu.getSubMenu()); 变量转换为字段并将引用保存到

on*ItemSelected

然后在switch (item.getItemId()) { case R.id.fp_pitcher: if (item == fp_menu.findItem(R.id.fp_pitcher)) { // selected inside teameditor_assignfieldingposition } else if (item == bp_menu.findItem(R.id.fp_picther)) { // selected inside teameditor_assignbattingposition } else { throw new ImLostInMenusException(); } return true; } return super.on*ItemSelected();

{{1}}

答案 1 :(得分:0)

它并不漂亮,但如果您需要这样做而不复制XML内容(这将很容易)。当您为第二个菜单充气时,您还可以为要添加的每个项目执行menu.findItem(R.id.teameditor_assignfieldingposition).getSubMenu().add(...)。如果在String数组资源中有字符串(“Pitcher”和“Catcher”),则可以迭代该数组以添加与原始数据相同的项目。或者,你可能需要解析另一个菜单的XML,你可以通过只是膨胀它来欺骗它,然后使用它size()getItem(int)

事实上,您可以将第一个菜单扩展为Menu,然后使用size()getItem(int)来获取MenuItem。然后,对于每个项目,您可以在第二个菜单add(menuItem.getGroupId(), menuItem.getItemId(), menuItem.getOrder(), menuItem.getTitle())的{​​{1}}上getSubMenu()进行操作。这应该将第一个菜单的所有项目添加为该项目的子菜单。这意味着你要膨胀两个XML文件,但是如果你想使用单独的XML文件那么这是不可避免的,因为菜单XML文件没有findItem(R.id.teameditor_assignfieldingposition)。我可能会正常膨胀第二个菜单(在<include>中)然后将第一个菜单添加为onCreateOptionsMenu(...)中的子菜单(它是您在onPrepareOptionsMenu(...)中创建的菜单)。我认为你可以在onCreateOptionsMenu(...)中完成所有操作,但我相信最好在onCreateOptionsMenu(...)修改菜单。

我认为第二种方式是我能找到的最佳解决方案,为了以防万一,我将第一种选择作为替代方案。