Simple question.
I have my menu of child items:
<?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>
And later I would want to include it as a submenu of this 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 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.
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(R.id.teameditor_assignfieldingposition).getSubMenu().add(...)
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'ssize()
andgetItem(int)
.In fact, you could just inflate the first menu into a
Menu
and then usesize()
andgetItem(int)
to get theMenuItem
s out of it. Then, for each item you can doadd(menuItem.getGroupId(), menuItem.getItemId(), menuItem.getOrder(), menuItem.getTitle())
on thegetSubMenu()
of the second menu'sfindItem(R.id.teameditor_assignfieldingposition)
. 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 theonCreateOptionsMenu(...)
) and then add the first menu as a submenu in theonPrepareOptionsMenu(...)
(it's given the menu you created inonCreateOptionsMenu(...)
). I think you could do it all inonCreateOptionsMenu(...)
, but I believe it's better practice to make modifications to the menu inonPrepareOptionsMenu(...)
.I think the second way is the best solution I can find, I'm leaving the first option as an alternative just in case.
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 aMenu
instance to include/inflate the other file into:You can put the above code to any of the following using the specified
inflater
:Activity.onCreateContextMenu(menu, v, menuInfo)
:getMenuInflater()
Fragment.onCreateContextMenu(menu, v, menuInfo)
:getActivity().getMenuInflater()
Activity.onCreateOptionsMenu(menu)
:getMenuInflater()
Fragment.onCreateOptionsMenu(menu, inflater)
:inflater
menu/player.xml
The empty
<menu />
placeholder is very important, without thatgetSubMenu()
will benull
!menu/positions.xml
Note on your
onContextItemSelected
ideaI 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 intogetSubMenu()
, 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
intoteameditor_assignbattingposition
as well you'll have some problems inonOptionsItemSelected
/onContextItemSelected
. One way to work around it is to convert thefindItem
variable to a field and save the reference to bothand then in
on*ItemSelected
: