So ändern Sie den Menüelementtext dynamisch in Android

212

Ich versuche, den Titel eines Menüelements von außerhalb der onOptionsItemSelected(MenuItem item)Methode zu ändern .

Ich mache schon folgendes;

public boolean onOptionsItemSelected(MenuItem item) {
  try {
    switch(item.getItemId()) {
      case R.id.bedSwitch:
        if(item.getTitle().equals("Set to 'In bed'")) {
          item.setTitle("Set to 'Out of bed'");
          inBed = false;
        } else {
          item.setTitle("Set to 'In bed'");
          inBed = true;
        }
        break;
    }
  } catch(Exception e) {
    Log.i("Sleep Recorder", e.toString());
  }
  return true;
}

Ich möchte jedoch in der Lage sein, den Titel eines bestimmten Menüelements außerhalb dieser Methode zu ändern.

Garbit
quelle
stackoverflow.com/a/32072318/1651286 sollte die akzeptierte Antwort sein
Akhil Dad

Antworten:

127

Wie JxDarkAngel vorgeschlagen hat, rufen Sie dies von überall in Ihrer Aktivität auf .

invalidateOptionsMenu();

und dann überschreiben:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
  MenuItem item = menu.findItem(R.id.bedSwitch);
    if (item.getTitle().equals("Set to 'In bed'")) {
        item.setTitle("Set to 'Out of bed'");
        inBed = false;
    } else {
        item.setTitle("Set to 'In bed'");
        inBed = true;
    }
  return super.onPrepareOptionsMenu(menu);
}

ist eine viel bessere Wahl. Ich habe die Antwort von https://stackoverflow.com/a/17496503/568197 verwendet

Todd DeLand
quelle
Beste Lösung. Weil diese eine Android-Methode überschreiben, anstatt das Rad neu zu erfinden.
Azlan Jamal
Beachten Sie nur, dass dies onPrepareOptionsMenu()vom Android-Framework ziemlich häufig aufgerufen wird, z. B. beim Anzeigen einer Aktivität und jedes Mal, wenn das Menü angezeigt wird. Dies ist möglicherweise nicht sehr effizient, wenn sich Ihr Menü nicht sehr oft ändert.
Mr-IDE
1
invalidateOptionsMenu()wird auch aufgerufen onCreateOptionsMenu(), so dass Sie die Aktualisierungslogik einfügen können onCreateOptionsMenu().
Mr-IDE
Wenn Sie dies bearbeiten, um für die Frage relevant zu sein, werde ich es als akzeptierte Antwort markieren
Garbit
@Garbit aktualisiert, um Ihren Code aus der ursprünglichen Frage zu verwenden!
Todd DeLand
375

Ich würde vorschlagen, innerhalb der Aktivität einen Verweis auf das Menüobjekt zu behalten, das Sie in onCreateOptionsMenu erhalten, und dieses dann zu verwenden, um das MenuItem abzurufen, für das die Änderung erforderlich ist, wenn Sie es benötigen. Sie könnten beispielsweise Folgendes tun:

public class YourActivity extends Activity {

  private Menu menu;
  private String inBedMenuTitle = "Set to 'In bed'";
  private String outOfBedMenuTitle = "Set to 'Out of bed'";
  private boolean inBed = false;

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);

    // Create your menu...

    this.menu = menu;
    return true;
  }

  private void updateMenuTitles() {
    MenuItem bedMenuItem = menu.findItem(R.id.bedSwitch);
    if (inBed) {
      bedMenuItem.setTitle(outOfBedMenuTitle);
    } else {
      bedMenuItem.setTitle(inBedMenuTitle);
    }
  }

}

Alternativ können Sie onPrepareOptionsMenu überschreiben , um die Menüelemente jedes Mal zu aktualisieren, wenn das Menü angezeigt wird.

Charles Harley
quelle
1
Ich erwarte immer, dass Android eine elegantere Lösung für diese Art von Problemen bietet. Die einfachsten Antworten scheinen oft die besten zu sein - danke.
Steven Wolfe
12

Sie können dazu ein globales "Menü" -Objekt erstellen und es dann in onCreateOptionMenu zuweisen

public class ExampleActivity extends AppCompatActivity
    Menu menu;

dann hier zuweisen

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu, menu);
    this.menu = menu;
    return true;
}

Verwenden Sie später das zugewiesene Menüobjekt, um die erforderlichen Elemente abzurufen

menu.findItem(R.id.bedSwitch).setTitle("Your Text");
Pranav Raut
quelle
5

Erstellen Sie eine setOptionsTitle () -Methode und legen Sie ein Feld in Ihrer Klasse fest. Sowie:

String bedStatus = "Set to 'Out of Bed'";

...

public void setOptionsTitle(String status)
{
    bedStatus = status;

}

Wenn das Menü nun ausgefüllt ist, ändern Sie den Titel in einen beliebigen Status:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);

        menu.add(bedStatus);


        // Return true so that the menu gets displayed.
        return true;
    }
Jack
quelle
Ich muss es einstellen können, nachdem die Aktivität gerendert wurde. Also also nicht in diesen beiden Methoden
Garbit
Rufen Sie setOptionsTitle jederzeit nach dem Rendern Ihrer Aktivität auf. Ich glaube, ich verstehe nicht, was Sie wollen, weil "Ich muss es einstellen können, nachdem die Aktivität gerendert wurde" für mich bedeutet, dass Sie nach dem Aufruf von setContent (R.layout.id) möglicherweise die Optionen ändern müssen Menüanzeigen (was Sie mit setOptionsTitle () tun können - von jeder Methode, überall und jederzeit).
Jack
Obwohl dieser Ansatz funktioniert, wird er nicht empfohlen, da das Menüobjekt, das das Menü verwaltet, nicht weiß, wann sich der Titel geändert hat, und daher nicht die Aufgaben ausführen kann, die erforderlich sind, wenn sich der Titel ändert, z. B. Layout und Zeilenumbrüche .
Charles Harley
3

Verwenden Sie besser die Überschreibung onPrepareOptionsMenu

menu.Clear ();
   if (TabActual == TabSelec.Anuncio)
   {
       menu.Add(10, 11, 0, "Crear anuncio");
       menu.Add(10, 12, 1, "Modificar anuncio");
       menu.Add(10, 13, 2, "Eliminar anuncio");
       menu.Add(10, 14, 3, "Actualizar");
   }
   if (TabActual == TabSelec.Fotos)
   {
       menu.Add(20, 21, 0, "Subir foto");
       menu.Add(20, 22, 1, "Actualizar");
   }
   if (TabActual == TabSelec.Comentarios)
   {
       menu.Add(30, 31, 0, "Actualizar");
   }

Hier ein Beispiel

JxDarkAngel
quelle
Verwenden Sie in der Tat den beabsichtigten Ansatz. :) Wenn Sie sich dafür entscheiden, einen lokalen Verweis auf das Menü beizubehalten, müssen Sie sich über Kontextlecks Gedanken machen, denke ich. Oder vielleicht nicht. Aber sicher nicht mit diesem Ansatz.
William T. Mallard
3

Ich benutze diesen Code, um mein unteres Navigationselement zu kostümieren

BottomNavigationView navigation = this.findViewById(R.id.my_bottom_navigation);
Menu menu = navigation.getMenu();
menu.findItem(R.id.nav_wall_see).setTitle("Hello");
Oumar
quelle
2

Deklarieren Sie Ihr Menüfeld.

private Menu menu;

Es folgt die Methode onCreateOptionsMenu ()

public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
    try {
        getMenuInflater().inflate(R.menu.menu_main,menu);
    } catch (Exception e) {
        e.printStackTrace();
        Log.i(TAG, "onCreateOptionsMenu: error: "+e.getMessage());
    }
    return super.onCreateOptionsMenu(menu);
}

Im Folgenden finden Sie Ihre Aktivität als Namensgeber. Entweder durch Klicken auf eine Schaltfläche oder durch bedingten Code

public void setMenuName(){
menu.findItem(R.id.menuItemId).setTitle(/*Set your desired menu title here*/);
}

Das hat bei mir funktioniert.

HyperCoder
quelle
0

Es scheint mir, dass Sie den Inhalt des Menüs innerhalb einer lokalen Methode ändern möchten, und diese Methode wird jederzeit aufgerufen, wenn ein Ereignis auftritt oder im Thread der Aktivitäts-Benutzeroberfläche.

Warum nehmen Sie nicht die Instanz von Menu in der globalen Variablen in onPrepareOptionsMenu, wenn diese überschrieben wird, und verwenden Sie sie in Ihrer Methode. Stellen Sie sicher, dass diese Methode aufgerufen wird, wenn ein Ereignis auftritt (z. B. Klicken auf eine Schaltfläche) oder im Thread, Handler oder Async-Task der Aktivität nach der Ausführung.

Sie sollten den Index dieses Menüelements, den Sie ändern möchten, im Voraus kennen. Nach dem Löschen des Menüs müssen Sie das Menü-XML aufblasen und den Namen oder das Symbol Ihres Elements aktualisieren.

Abhinav Saxena
quelle
0

Für Personen, bei denen der Titel statisch festgelegt werden muss. Dies kann in der AndroidManifest.xml erfolgen

<activity
    android:name=".ActivityName"
    android:label="Title Text" >
</activity>

Optionen Menü Titel Text

Moberme
quelle
3
Fragen sind für dynamisch, nicht statisch!
EngineSense
kam immer noch auf Google-Suche und half mir, danke für die Veröffentlichung
Bruchowski
0

Ich musste das Menüsymbol für das Fragment ändern. Ich habe Charles 'Antwort auf diese Frage für das Fragment ein wenig geändert:

    private Menu top_menu;

    //...
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

       setHasOptionsMenu(true);
       //...
       rootview = inflater.inflate(R.layout.first_content,null);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.fragment_menu, menu);
        this.top_menu = menu;
    }


    // my procedure
    private void updateIconMenu() {
         if(top_menu!= null) {
             MenuItem nav_undo = top_menu.findItem(R.id.action_undo);
             nav_undo.setIcon( R.drawable.back);
         }
    }
Almaz Vildanov
quelle