Android: ¿Cómo incluir un menú xml dentro de otro menú xml?

Pregunta simple.

Tengo mi menú de artículos para niños:

<?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> 

Y más tarde me gustaría incluirlo como un submenú de este menú:

 <?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> 

La pregunta aquí tipo de respuesta a esto – No estoy seguro de cómo inflar el submenú.

Estoy pensando que se infla en el método onContextItemSelected – pero inflar requiere un objeto de menú, que no se pasa a onContextItemSelected.

Lamentablemente no es posible en XML sin formato, pero hay una manera agradable sin utilizar manual Menu.add* métodos: aquí es cómo puede obtener una instancia de Menu para incluir / inflar el otro archivo en:

 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 /> 

Usted puede poner el código anterior a cualquiera de los siguientes utilizando el inflater especificado:

  • 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

 <?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> 

El vacío <menu /> marcador de posición es muy importante , sin que getSubMenu() será null !

Menu / positions.xml

 <?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> 

Nota sobre su idea onContextItemSelected

Estoy pensando que usted lo infla en el método onContextItemSelected […]

Creo que es demasiado tarde si usted está en onContextItemSelected , ya que ya está manejando el evento que llevaría a mostrar que está submenú … que no está inflada todavía. Usted podría intentar el mismo inflar en getSubMenu() , pero no estoy seguro de que va a aparecer. Lo mejor es crear el menú donde se supone que se creará.

Nota sobre la inclusión del mismo submenú varias veces en el mismo menú

No probado Si necesita inflar el mismo positions.xml en teameditor_assignbattingposition , también tendrá algunos problemas en onOptionsItemSelected / onContextItemSelected . Una manera de findItem es convertir la variable findItem en un campo y guardar la referencia a ambos

 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()); 

Y luego en 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(); 

No es bonito, pero si usted necesita hacerlo sin copiar el contenido XML (que podría funcionar fácilmente). Cuando infle el segundo menú, también puede hacer un menu.findItem(R.id.teameditor_assignfieldingposition).getSubMenu().add(...) para cada uno de los elementos que desea agregar. Si tiene las cadenas ("Pitcher" y "Catcher") en un recurso de matriz de cadenas, puede iterar sobre esa matriz para agregar los mismos elementos que en el original. Por otra parte, probablemente tendría que analizar el XML del otro menú, puede engañar que por sólo inflar, supongo, y luego utilizar su size() y getItem(int) .

De hecho, usted podría apenas inflar el primer menú en un Menu y después utilizar size() y getItem(int) para conseguir el MenuItem s fuera de él. A continuación, para cada elemento que puede hacer add(menuItem.getGroupId(), menuItem.getItemId(), menuItem.getOrder(), menuItem.getTitle()) en el getSubMenu() del getSubMenu() del segundo menú findItem(R.id.teameditor_assignfieldingposition) . Que debe agregar todos los elementos del primer menú como un submenú de ese elemento. Esto significa que está inflando dos archivos XML, pero es algo inevitable si desea utilizar archivos XML separados, ya que no hay un <include> para los archivos XML del menú. Probablemente hinchar el segundo menú normalmente (en el onCreateOptionsMenu(...) ) y luego agregar el primer menú como un submenú en el onPrepareOptionsMenu(...) (se le da el menú que creó en onCreateOptionsMenu(...) ) . Creo que podrías hacerlo todo en onCreateOptionsMenu(...) , pero creo que es mejor hacer modificaciones al menú en onPrepareOptionsMenu(...) .

Creo que la segunda forma es la mejor solución que puedo encontrar, estoy dejando la primera opción como una alternativa por si acaso.

  • Si declaro un fragmento en un diseño XML, ¿cómo lo apruebo un paquete?
  • Android: textColor del botón deshabilitado en el selector no se muestra?
  • Android LinearGradient XML
  • Manifiesto de Android que genera automáticamente permiso no válido
  • Xml vs. sqlite para android y cómo
  • ¿El análisis de archivos xml en android ocurre en tiempo de ejecución o tiempo de compilación?
  • ¿Cómo puedo hacer un diamante ShapeDrawable?
  • El atributo no se declara (Android) en los atributos xml básicos
  • Hola World Android App, Error: espacio de trabajo \ appcompat_v7 \ res \ values-v21 \ styles_base.xml Ningún recurso encontrado que coincida con el nombre dado
  • Cambiar el fondo del botón alfa sin cambiar el valor del alfabeto del texto en Android?
  • Cómo crear una nueva línea o pestaña en <string> XML (eclipse / android)?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.