android: programmgesteuertes Ändern von Optionsmenüelementen


89

Ist es möglich, die Optionsmenüpunkte programmgesteuert zu ändern? Kann mir bitte jemand ein Beispiel geben?

Außerdem möchte ich bestimmte Elemente deaktivieren, damit sie nicht auf die Klicks hören. Ist das möglich?

Antworten:


211

Denn jeder muss die Optionen des Menüs dynamisch ändern:

private Menu menu;

// ...

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

// ...

private void hideOption(int id)
{
    MenuItem item = menu.findItem(id);
    item.setVisible(false);
}

private void showOption(int id)
{
    MenuItem item = menu.findItem(id);
    item.setVisible(true);
}

private void setOptionTitle(int id, String title)
{
    MenuItem item = menu.findItem(id);
    item.setTitle(title);
}

private void setOptionIcon(int id, int iconRes)
{
    MenuItem item = menu.findItem(id);
    item.setIcon(iconRes);
}

8
Eine Einschränkung ist, dass Sie sicherstellen müssen, dass menudies eingestellt wurde, bevor Sie versuchen, es MenuItemherauszuholen. Wenn Sie beispielsweise so etwas haben actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS), werden die Registerkarten vor dem Menü geladen, sodass das Aufrufen von hideOption/ showOptioninside onTabSelectedzu einer Nullzeigerausnahme führt.
SaltyNuts

Wenn ich benutze item.setVisible(false);, wird das Element nur ausgeblendet, wenn ich auf das Menü selbst klicke. Wenn ich invalidateOptionsMenu();den Artikel verwende, antworte ich nicht auf das Klicken. Ich freue mich, wenn Sie mir bei einem ähnlichen Problem helfen könnten, mit dem ich konfrontiert bin. stackoverflow.com/questions/54756799/…
Aliton Oliveira

@AlitonOliveira Sie sollten Ihren item.setVisibility (false) -Teil in die onCreateOptionsMenu-Methode einfügen, indem Sie den Status Ihrer Flagvariablen überprüfen und den Bool-Wert Ihres Flags und von invalidateOptionsMenu ändern. es wird klappen.
Kidus Tekeste

Die Dokumentation der setVisibleZustände, die Sie auch anrufen sollten, setEnabled(false)andernfalls kann das Element weiterhin über die Verknüpfung aufgerufen werden
Florian Walther

34

menu.xml

  <item 
    android:id="@+id/item1"
    android:title="your Item">
  </item>

in deine Java-Datei einfügen

  public void onPrepareOptionsMenu(Menu menu) {

    menu.removeItem(R.id.item1);
}

Dies ist die, nach der ich gesucht habe, weil ich die Entscheidung einmal zur Laufzeit treffen möchte, aber die Optionen danach nicht mehr ändern muss. Ich habe verwendet: @Override public boolean onPrepareOptionsMenu (Menü menu) {if (! ShowItemName) {menu.removeItem (R.id.itemname); } return true; }
notmystyle


7

Wenn ich den Inhalt meines Optionsmenüs ändern muss, führe ich ihn während des onMenuOpened () aus. Auf diese Weise kann ich den Betriebszustand in dem Moment überprüfen, in dem der Benutzer auf das Menü zugreift.

public boolean onMenuOpened(int featureid, Menu menu)
    {
        menu.clear();
        if (!editable)
        {
            MenuItem itemAdd = menu.add(0, REASSIGN, Menu.NONE, context.getString(R.string.reassign));
            MenuItem itemMod = menu.add(1, EDIT, Menu.NONE, context.getString(R.string.modify));
            MenuItem itemDel = menu.add(2, DELETE, Menu.NONE, context.getString(R.string.delete));
            itemAdd.setShortcut('0', 'a');
            itemMod.setShortcut('1', 'm');
            itemDel.setShortcut('2', 'd');
        }
        else
        {
            MenuItem itemSave = menu.add(3, SAVE, Menu.NONE, context.getString(R.string.savechanges));
            itemSave.setShortcut('0', 'S');
        }


        return true;
    }

Ein paar kommentierende Worte. onMenuOpened wird zweimal aufgerufen. Das erste Mal ist die Menüvariable null, das zweite Mal ist die Menüvariable für die Verwendung vorbereitet. Ich benutze immer die 'if'-Klausel, um zu überprüfen, ob menu var nicht null ist.
Ksiądz Pistolet

7

So deaktivieren Sie bestimmte Elemente:

MenuItem item = menu.findItem(R.id.ID_ASSING_TO_THE_ITEM_IN_MENU_XML);
item.setEnabled(false);

Beim Festlegen item.setVisible(false);wird mein Element nur ausgeblendet, wenn ich auf das Menü selbst klicke (drei Punkte). Wenn ich invalidateOptionsMenu();einige Elemente verwende, reagieren Sie nicht auf das Klicken. Ich freue mich, wenn Sie mir bei einem ähnlichen Problem helfen könnten, mit dem ich konfrontiert bin. stackoverflow.com/questions/54756799/…
Aliton Oliveira

4

Mit den folgenden Zeilen habe ich die Werte im Menü hinzugefügt

getActivity().invalidateOptionsMenu();

Versuchen Sie diese Arbeit wie ein Zauber für mich.


3

Versuchen Sie diesen Code:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    this.menu=menu;
    updateMenuItems(menu);
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.document_list_activity_actions, menu);
    return super.onCreateOptionsMenu(menu);
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle presses on the action bar items
    if (item.getItemId() == android.R.id.home) {
        onHomeButtonPresssed();
    }else if (item.getItemId() == R.id.action_delete) {
        useCheckBoxAdapter=false;
        deleteDocuments();
    } else if (item.getItemId() == R.id.share) {
        useCheckBoxAdapter=false;
        shareDocuments();
    } else if (item.getItemId() == R.id.action_tick) {
        useCheckBoxAdapter=true;
        onShowCheckboxes();
    }
    updateMenuItems(menu);
    return true;
}

private void updateMenuItems(Menu menu){
    if (useCheckBoxAdapter && menu != null) {
        menu.findItem(R.id.action_delete).setVisible(true);
        menu.findItem(R.id.share).setVisible(true);
        menu.findItem(R.id.action_tick).setVisible(false);
    } else {
        menu.findItem(R.id.action_delete).setVisible(false);
        menu.findItem(R.id.share).setVisible(false);
        menu.findItem(R.id.action_tick).setVisible(true);
    }
    invalidateOptionsMenu();
}

Wenn ich benutze invalidateOptionsMenu();, funktionieren meine immer sichtbaren Elemente nicht mehr (ich meine, die Elemente reagieren nicht auf Klicks). Ich freue mich, wenn Sie mir bei einem ähnlichen Problem helfen könnten, mit dem ich konfrontiert bin. stackoverflow.com/questions/54756799/…
Aliton Oliveira

2

Sie können etwas Einfaches tun, wie ich es getan habe. Ändern Sie einfach den Text in den gewünschten Text, wenn Sie den Menüpunkt berühren. Ich musste den Ton ein- und ausschalten sowie die Möglichkeit, eine Aktion durch Berühren auszuführen. Hier ist mein Code:

    @Override
public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
    case R.id.audioOn:
        audioOn = !audioOn;
        if (audioOn)
            item.setTitle("Audio Off");
        else
            item.setTitle("Audio On");
        return true;

    case R.id.touchOn:
        touchOn = !touchOn;
        if (touchOn)
            item.setTitle("Touch Off");
        else
            item.setTitle("Touch On");
        return true;
    default:
        return super.onOptionsItemSelected(item);
    }
}

audioOn und touchOn sind Boolesche Werte, die in anderen Teilen des Codes überprüft werden. Hoffe das hilft.


Wie kann ich das dynamisch machen? Ich meine ... einen Webservice bei Auswahl eines Optionselements und dann bei dessen erfolgreicher Antwort aufrufen ... onCreateOptionsMenu erneut aufrufen. Wie geht das?
Narendra Singh

1

Sie können Ihre Aufgabe einfach durch Implementierung wie folgt erfüllen:

private Menu menu;

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

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    this.menu = menu;
    return super.onPrepareOptionsMenu(menu);
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    if (id == R.id.action_toggle_grid) {
        handleMenuOption(id);
        return true;

    } else if(id == R.id.action_toggle_list){
        handleMenuOption(id);
        return true;
    }

    return super.onOptionsItemSelected(item);
}

private void handleMenuOption(int id) {
    MenuItem item = menu.findItem(id);
    if (id == R.id.action_toggle_grid){
        item.setVisible(false);
        menu.findItem(R.id.action_toggle_list).setVisible(true);
    }else if (id == R.id.action_toggle_list){
        item.setVisible(false);
        menu.findItem(R.id.action_toggle_grid).setVisible(true);
    }
}

1

Falls Sie eine BottomBar haben:

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    if (mBottomBar.getCurrentTabId() == R.id.tab_more) {
        getMenuInflater().inflate(R.menu.more_menu, menu);
    }

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.preferences:
            startActivity(new Intent(this, PreferenceActivity.class));
            break;
    }

    return super.onOptionsItemSelected(item);
}

Dann müssen Sie nur noch anrufen:

@Override
public void onBottomBarClick(int tabId) {
    supportInvalidateOptionsMenu();
}

1

Kotlin-Code für den programmgesteuerten Zugriff auf OptionsmenüoptionenMenüelemente und Ändern des Texts / Symbols, ..:

1-Wir haben unseren Menüpunkt in der Menüpunktdatei wie: menu.xml, Beispielcode dafür:

 <?xml version="1.0" encoding="utf-8"?> 
 <menu xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/balance"
      android:title="0"
      android:orderInCategory="100"
      app:showAsAction="always" />
 </menu>

2- Definieren Sie eine Variable für den Zugriff auf Menüobjekte in der Klasse:

var menu: Menu? = null

3- Initialisieren Sie es in onCreateOptionsMenu:

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    // Inflate the menu; this adds items to the action bar if it is present.
    menuInflater.inflate(R.menu.main, menu)
    this.menu = menu
    return true
}

4- Greifen Sie auf die Menüelemente in Ihrem Code oder Spaß zu:

private fun initialBalanceMenuItemOnToolbar() {
var menuItemBalance = menu?.findItem(R.id.balance)
    menuItemBalance?.title = Balance?.toString() ?: 0.toString()
    // for change icon : menuWalletBalance?.icon
}

1
@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.calendar, menu);
        if(show_list == true) {         

        if(!locale.equalsIgnoreCase("sk")) menu.findItem(R.id.action_cyclesn).setVisible(false);

        return true;
    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.