6 Stimmen

Android: Wie kann man eine Menü-XML in eine andere Menü-XML einfügen?

Eine einfache Frage.

Ich habe mein Menü mit Kinderartikeln:

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

Und später möchte ich es als Untermenü dieses Menüs einfügen:

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

Die Frage hier irgendwie beantwortet - ich bin nicht sicher, wie man das Untermenü aufbläst.

Ich denke, dass Sie es in der onContextItemSelected-Methode aufblasen - aber inflate erfordert ein Menüobjekt, das nicht in onContextItemSelected übergeben wird.

3voto

TWiStErRob Punkte 41031

Es ist leider nicht möglich, in einfachem XML, aber es gibt einen schönen Weg, ohne manuelle Menu.add* Methoden: So können Sie eine Menu Instanz, in die die andere Datei einzuschließen/einzublenden ist:

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

Sie können den obigen Code in jede der folgenden Zeilen einfügen, indem Sie die angegebene inflater :

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

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

Die leere <menu /> Platzhalter ist sehr wichtig , ohne diese getSubMenu() wird sein null !

menü/stellungen.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>

Anmerkung zu Ihrem onContextItemSelected Idee

Ich denke, Sie blasen es in der onContextItemSelected Methode [...]

Ich denke, es ist zu spät, wenn Sie in onContextItemSelected da Sie bereits das Ereignis behandeln, das dazu führen würde, dass das Untermenü angezeigt wird, das noch nicht aufgeblasen ist. Sie könnten versuchen, das gleiche inflate in getSubMenu() aber ich bin mir nicht sicher, ob es auftauchen wird. Am besten ist es, das Menü dort zu erstellen, wo es erstellt werden soll.

Hinweis zur mehrfachen Aufnahme desselben Untermenüs in dasselbe Menü

Ungetestet Wenn Sie dasselbe aufblasen müssen positions.xml in teameditor_assignbattingposition haben Sie auch einige Probleme in onOptionsItemSelected / onContextItemSelected . Eine Möglichkeit, dieses Problem zu umgehen, ist die Konvertierung der findItem auf ein Feld und speichern Sie den Verweis auf beide

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

und dann in 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();

0voto

Dandre Allison Punkte 5895

Es ist nicht schön, aber wenn Sie es tun müssen, ohne Kopieren der XML-Inhalt über (die leicht funktionieren würde). Wenn Sie das zweite Menü aufblasen, können Sie auch eine menu.findItem(R.id.teameditor_assignfieldingposition).getSubMenu().add(...) für jedes der Elemente, die Sie hinzufügen möchten. Wenn Sie die Strings ("Pitcher" und "Catcher") in einer String-Array-Ressource haben, können Sie über dieses Array iterieren, um die gleichen Elemente wie im Original hinzuzufügen. Alternativ müssten Sie wahrscheinlich das XML des anderen Menüs parsen, Sie können das umgehen, indem Sie es einfach aufblasen und dann die size() y getItem(int) .

Eigentlich könnte man das erste Menü einfach aufblasen in ein Menu und verwenden Sie dann size() y getItem(int) um die MenuItem s aus. Dann können Sie für jedes Element Folgendes tun add(menuItem.getGroupId(), menuItem.getItemId(), menuItem.getOrder(), menuItem.getTitle()) sur le getSubMenu() des zweiten Menüs findItem(R.id.teameditor_assignfieldingposition) . Dadurch sollten alle Einträge des ersten Menüs als Untermenü dieses Eintrags hinzugefügt werden. Das bedeutet, dass Sie zwei XML-Dateien aufblasen, aber das ist irgendwie unvermeidlich, wenn Sie separate XML-Dateien verwenden wollen, da es keine <include> für Menü-XML-Dateien. Ich würde wahrscheinlich das zweite Menü normal aufblasen (in der onCreateOptionsMenu(...) ) und fügen Sie dann das erste Menü als Untermenü in der onPrepareOptionsMenu(...) (es wird das Menü angezeigt, das Sie in onCreateOptionsMenu(...) ). Ich denke, Sie könnten das alles in onCreateOptionsMenu(...) aber ich glaube, es ist besser, Änderungen am Menü in onPrepareOptionsMenu(...) .

Ich denke, dass der zweite Weg die beste Lösung ist, die ich finden kann, ich lasse die erste Option als Alternative für den Fall.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X