Android: cambiar los elementos del menú de opciones mediante programación


89

¿Es posible cambiar los elementos del menú de opciones mediante programación? ¿Alguien me puede dar un ejemplo por favor?

Además, quiero deshabilitar ciertos elementos para que no escuchen los clics, ¿es posible?

Respuestas:


211

Cualquiera necesita cambiar las opciones del menú de forma dinámica:

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
Una advertencia es que debe asegurarse de que menuse haya configurado antes de intentar obtener una MenuItemsalida. Por ejemplo, si tiene algo como actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS), las pestañas se cargan antes del menú, por lo que llamar hideOption/ showOptiondentro onTabSelectedda como resultado una excepción de puntero nulo.
SaltyNuts

Cuando lo uso item.setVisible(false);, el elemento solo se oculta cuando hago clic en el menú. Si utilizo invalidateOptionsMenu();el artículo no respondo al clic. Le agradecería que me ayudara con un problema similar al que me enfrento. stackoverflow.com/questions/54756799/…
Aliton Oliveira

@AlitonOliveira debe poner su parte item.setVisibility (false) dentro del método onCreateOptionsMenu verificando el estado de la variable de su bandera y debe cambiar el valor bool de su bandera e invalidateOptionsMenu. funcionará.
Kidus Tekeste

La documentación de los setVisibleestados a los que también debe llamar; de lo setEnabled(false)contrario, el elemento aún se puede invocar a través de su acceso directo
Florian Walther

34

menu.xml

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

poner en su archivo java

  public void onPrepareOptionsMenu(Menu menu) {

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

Este es el que estaba buscando porque quiero tomar la decisión una vez en tiempo de ejecución, pero no necesito cambiar las opciones después. Usé: @Override public boolean onPrepareOptionsMenu (menú de menú) {if (! ShowItemName) {menu.removeItem (R.id.itemname); } devuelve verdadero; }
notmystyle


7

Si tengo que cambiar el contenido de mi menú de opciones, lo hago durante el onMenuOpened (). Esto me permite verificar el estado de ejecución en el mismo momento en que el usuario accede al menú.

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

Algunas palabras de comentario. onMenuOpened se llama dos veces. La var del menú de primera vez es nula, la var de menú de la segunda vez está preparada para su uso. Siempre uso la cláusula 'if' para verificar si el menú var no es nulo.
Ksiądz Pistolet

7

Para deshabilitar ciertos elementos:

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

Cuando lo configuro item.setVisible(false);, mi elemento solo se oculta cuando hago clic en el menú (tres puntos). Si utilizo invalidateOptionsMenu();algunos elementos no respondo al hacer clic. Agradezco que me ayuden con un problema similar al que me enfrento. stackoverflow.com/questions/54756799/…
Aliton Oliveira

4

usando las siguientes líneas que he hecho para agregar los valores en el menú

getActivity().invalidateOptionsMenu();

prueba este trabajo como un encanto para mí.


3

Prueba este código:

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

Cuando lo uso invalidateOptionsMenu();, mis elementos siempre visibles dejan de funcionar (me refiero a que los elementos no responden al clic). Agradezco que me ayuden con un problema similar al que me enfrento. stackoverflow.com/questions/54756799/…
Aliton Oliveira

2

Puedes hacer algo simple como lo hice yo. Simplemente cambie el texto a lo que se necesita cuando se toca el elemento del menú. Necesitaba apagar y encender el sonido, además de poder realizar una acción tocándolo. Aquí está mi código:

    @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 y touchOn son valores booleanos marcados en otras partes del código. Espero que esto ayude.


¿Cómo puedo hacer esto de forma dinámica? Quiero decir ... llamar a un servicio web para seleccionar un elemento de opción y luego en su respuesta exitosa ... volver a llamar onCreateOptionsMenu. ¿Cómo hacerlo?
Narendra Singh

1

puede realizar su tarea simplemente implementando como se muestra a continuación:

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

En caso de que tenga 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);
}

Entonces solo necesitas llamar:

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

1

Código Kotlin para acceder a los elementos del menú Opciones de la barra de herramientas mediante programación y cambiar el texto / icono, ..:

1-Tenemos nuestro elemento de menú en un archivo de elementos de menú como: menu.xml, código de muestra para esto:

 <?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- Defina una variable para acceder al objeto de menú en clase:

var menu: Menu? = null

3- Ponga sus iniciales en 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- Accede a los elementos del menú dentro de tu código o diversión:

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;
    }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.