android: alterar itens do menu de opções de maneira programática


89

É possível alterar os itens do menu de opções programaticamente? Alguém pode me dar um exemplo, por favor?

Além disso, quero desabilitar alguns itens, para que não escutem os cliques, é possível?

Respostas:


211

Para qualquer um precisa alterar as opções do menu dinamicamente:

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
Uma ressalva é que você deve certificar-se de que menufoi definido antes de tentar obter um MenuItemresultado. Por exemplo, se você tiver algo como actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS), as guias são carregadas antes do menu, portanto, chamar hideOption/ showOptiondentro onTabSelectedresulta em uma exceção de ponteiro nulo.
SaltyNuts

Quando eu uso item.setVisible(false);, o item só fica oculto quando clico no próprio Menu. Se eu usar invalidateOptionsMenu();o item não responda ao clique. Agradeço se você puder me ajudar em um problema semelhante que estou enfrentando. stackoverflow.com/questions/54756799/…
Aliton Oliveira

@AlitonOliveira você deve colocar sua parte item.setVisibility (false) dentro do método onCreateOptionsMenu, verificando o status da variável do seu flag e você deve alterar o valor bool do seu flag e invalidateOptionsMenu. vai funcionar.
Kidus Tekeste

A documentação setVisibleindica que você também deve ligar, setEnabled(false)caso contrário, o item ainda pode ser invocado por meio de seu atalho
Florian Walther

34

menu.xml

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

coloque em seu arquivo java

  public void onPrepareOptionsMenu(Menu menu) {

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

Este é o que eu estava procurando porque quero tomar a decisão uma vez no tempo de execução, mas não preciso alterar as opções depois. Eu usei: @Override public boolean onPrepareOptionsMenu (Menu menu) {if (! ShowItemName) {menu.removeItem (R.id.itemname); } return true; }
notmystyle


7

Se eu tiver que mudar o conteúdo do meu menu de opções, eu faço durante o onMenuOpened (). Isso me permite verificar o estado de execução no momento em que o usuário está acessando o 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;
    }

Algumas palavras de comentário. onMenuOpened é chamado duas vezes. O menu var da primeira vez é nulo, o menu var da segunda vez é preparado para uso. Eu sempre uso a cláusula 'if' para verificar se o menu var não é nulo.
Ksiądz Pistolet

7

Para desativar certos itens:

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

Quando eu defino item.setVisible(false);, meu item só fica oculto quando eu clico no próprio Menu (três pontos). Se eu usar invalidateOptionsMenu();alguns itens não respondem ao clique. Agradeço se você puder me ajudar em um problema semelhante que estou enfrentando. stackoverflow.com/questions/54756799/…
Aliton Oliveira

4

usando as seguintes linhas eu fiz para adicionar os valores no menu

getActivity().invalidateOptionsMenu();

tente este trabalho como um encanto para mim.


3

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

Quando eu uso invalidateOptionsMenu();, meus itens sempre visíveis param de funcionar (quero dizer, os itens não respondem ao clique). Agradeço se você puder me ajudar em um problema semelhante que estou enfrentando. stackoverflow.com/questions/54756799/…
Aliton Oliveira

2

Você pode fazer algo simples como eu fiz. Basta alterar o texto para o que é necessário quando o item de menu é tocado. Eu precisava desligar e ligar o som, além da capacidade de realizar uma ação ao tocá-lo. Aqui está o meu 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 e touchOn são booleanos verificados em outras partes do código. Espero que isto ajude.


Como posso fazer isso dinamicamente. Quero dizer ... chamar um serviço da web ao selecionar um item de opção e, em seguida, em sua resposta bem-sucedida ... chamar novamente onCreateOptionsMenu. Como fazer isso?
Narendra Singh

1

você pode realizar sua tarefa simplesmente implementando o seguinte:

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

Caso você tenha uma 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);
}

Então você só precisa ligar para:

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

1

Código Kotlin para acessar os itens do menu Opções da barra de ferramentas de forma programática e alterar o texto / ícone ..:

1-Temos nosso item de menu no arquivo de itens de menu como: menu.xml, código de amostra para este:

 <?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 uma variável para acessar o objeto de menu na classe:

var menu: Menu? = null

3- inicialize-o em 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- Acesse os itens do menu dentro do seu código ou diversão:

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;
    }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.