android: modifica programmatica delle voci del menu delle opzioni


89

È possibile modificare le voci del menu delle opzioni a livello di programmazione? Qualcuno può fornirmi un esempio per favore?

Inoltre, desidero disabilitare alcuni elementi, in modo che non ascoltino i clic, è possibile?

Risposte:


211

Per chiunque è necessario modificare le opzioni del menu in modo dinamico:

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
Un avvertimento è che devi assicurarti che menusia stato impostato prima di tentare di ottenerne uno MenuItem. Ad esempio, se hai qualcosa di simile actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS), le schede vengono caricate prima del menu, quindi la chiamata hideOption/ showOptionall'interno onTabSelectedproduce un'eccezione del puntatore nullo.
SaltyNuts

Quando lo uso item.setVisible(false);, l'elemento viene nascosto solo quando faccio clic sul menu stesso. Se utilizzo invalidateOptionsMenu();l'elemento non rispondo al clic. Apprezzo se potessi aiutarmi su un problema simile che sto affrontando. stackoverflow.com/questions/54756799/...
Aliton Oliveira

@AlitonOliveira dovresti mettere la tua parte item.setVisibility (false) nel metodo onCreateOptionsMenu controllando lo stato della tua variabile flag e dovresti cambiare il valore bool della tua bandiera e invalidateOptionsMenu. Funzionerà.
Kidus Tekeste

La documentazione degli setVisiblestati che dovresti anche chiamare setEnabled(false)altrimenti l'oggetto può ancora essere richiamato tramite la sua scorciatoia
Florian Walther

34

menu.xml

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

inserisci il tuo file java

  public void onPrepareOptionsMenu(Menu menu) {

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

Questo è quello che stavo cercando perché voglio prendere la decisione una volta in fase di esecuzione ma non è necessario modificare le opzioni dopo. Ho usato: @Override public boolean onPrepareOptionsMenu (Menu menu) {if (! ShowItemName) {menu.removeItem (R.id.itemname); } restituisce vero; }
notmystyle


7

Se devo cambiare il contenuto del mio menu delle opzioni lo eseguo durante onMenuOpened (). Questo mi permette di controllare lo stato di esecuzione nel momento in cui l'utente accede al menu.

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;
    }

Poche parole di commento. onMenuOpened viene chiamato due volte. La prima volta che il menu var è nullo, la seconda volta che il menu var è preparato per l'uso. Uso sempre la clausola "if" per verificare se il menu var non è nullo.
Ksiądz Pistolet

7

Per disabilitare determinati elementi:

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

Quando eseguo l'impostazione item.setVisible(false);, il mio elemento viene nascosto solo quando faccio clic sul menu stesso (tre punti). Se utilizzo invalidateOptionsMenu();alcuni elementi non rispondono al clic. Apprezzo se potessi aiutarmi su un problema simile che sto affrontando. stackoverflow.com/questions/54756799/...
Aliton Oliveira

4

utilizzando le seguenti righe ho fatto per aggiungere i valori nel menu

getActivity().invalidateOptionsMenu();

prova questo lavoro come un fascino per me.


3

Prova questo codice:

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

Quando lo uso invalidateOptionsMenu();, i miei elementi sempre visibili smettono di funzionare (intendo dire che gli elementi non rispondono al clic). Apprezzo se potessi aiutarmi su un problema simile che sto affrontando. stackoverflow.com/questions/54756799/...
Aliton Oliveira

2

Puoi fare qualcosa di semplice come ho fatto io. Basta cambiare il testo in ciò che è necessario quando viene toccata la voce di menu. Avevo bisogno di attivare e disattivare il suono, oltre alla possibilità di eseguire un'azione toccandolo. Ecco il mio codice:

    @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 e touchOn sono booleani controllati in altre parti del codice. Spero che questo ti aiuti.


Come posso farlo dinamicamente. Voglio dire ... chiamare un servizio web sulla selezione di un elemento di opzione e poi sulla sua risposta positiva ... richiamare nuovamente onCreateOptionsMenu. Come farlo?
Narendra Singh

1

puoi svolgere il tuo compito semplicemente implementando come di seguito:

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

Nel caso tu abbia una BottomBar:

@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);
}

Quindi devi solo chiamare:

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

1

Kotlin Codice per l'accesso alle opzioni della barra degli strumenti Elementi del menu a livello di programmazione e modifica del testo / icona, ..:

1-Abbiamo la nostra voce di menu nel file di voci di menu come: menu.xml, codice di esempio per questo:

 <?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- Definisci una variabile per accedere all'oggetto menu in classe:

var menu: Menu? = null

3- inizializzalo 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- Accedi alle voci di menu all'interno del tuo codice o divertiti:

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;
    }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.