Como oculto um item de menu na barra de ação?

346

Eu tenho uma barra de ação com um menu. Como posso ocultar / mostrar esse item de menu?

Isto é o que estou tentando fazer:

MenuItem item = (MenuItem) findViewById(R.id.addAction);
item.setVisible(false);
this.invalidateOptionsMenu();
Stir Zoltán
fonte

Respostas:

484

Obter um MenuItemapontador para tal item, chamada setVisiblenele para ajustar a sua visibilidade e, em seguida, chamar invalidateOptionsMenu()em sua atividade para que o menu ActionBar é ajustado em conformidade.

Atualização: A MenuItemnão é uma visualização regular que faz parte do seu layout. É algo especial, completamente diferente. Seus retornos de código nullpara iteme que está causando o acidente. O que você precisa é fazer:

MenuItem item = menu.findItem(R.id.addAction);

Aqui está a sequência na qual você deve chamar: primeira chamada invalidateOptionsMenu()e depois onCreateOptionsMenu(Menu)obter uma referência ao MenuItem (chamando menu.findItem()) e chamar setVisible()por ele

K-ballo
fonte
Isso é o que eu pensei inicialmente, mas isso trava o aplicativo.
Stir Zoltán
3
@Stir Zoltán: Bem, é assim que você faz, você pode estar fazendo errado se travar o aplicativo. Por exemplo, você MenuItempode estar nullporque está usando em getItemvez de findItem. Nós nunca poderíamos saber, sem ver o seu código e o log de falhas.
K-ballo
OK, mas como posso obter uma referência ao menu fora do método onCreateOptionsMenu?
Stir Zoltán
7
@Stir Zoltán: Eu acredito que você não faz sentido com esse último comentário ... Basta obter uma referência ao item do menu em onCreateOptionsMenue definir a visibilidade do item nesse ponto. Ou mantenha a referência por perto até decidir se ela deve ser visível ou não.
K-ballo
33
Penso que (na melhor das hipóteses) essa resposta está mal formulada porque a sequência de etapas está errada. A sequência correta é a primeira chamada invalidateOptionsMenu()e, em seguida, dentro de onCreateOptionsMenu(Menu)obter uma referência para o MenuItem(chamando menu.findItem()) e chamá setVisible()-lo. As respostas de suhas_sm e de P1r4nh4 apresentam a abordagem correta.
precisa
163

Encontrou um adendo para esta pergunta:

Se você quiser alterar a visibilidade de seus itens de menu em qualquer lugar, basta definir uma variável de membro em sua atividade para lembrar que deseja ocultar o menu e chamar invalidateOptionsMenu()e ocultar os itens no seu onCreateOptionsMenu(...)método substituído .

//anywhere in your code
...
mState = HIDE_MENU; // setting state
invalidateOptionsMenu(); // now onCreateOptionsMenu(...) is called again
...

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    // inflate menu from xml
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.settings, menu);

    if (mState == HIDE_MENU)
    {
        for (int i = 0; i < menu.size(); i++)
            menu.getItem(i).setVisible(false);
    }
}

No meu exemplo, eu escondi todos os itens.

P1r4nh4
fonte
2
É exatamente isso que eu tenho procurado. segurar o MenuItem e chamar setVisible () não pareceu fazer o que eu esperava (talvez porque eu estivesse chamando invalidateOptionsMenu () depois, reconstruindo o menu), mas de qualquer forma - isso funciona exatamente como eu esperava, obrigado!
Matt
4
Se você deseja ocultar todos os itens, existe uma maneira mais fácil. Em vez de percorrer cada item aqui, você pode fazer o seguinte: if (HIDE_MENU) { return false; } else { getSupportMenuInflater().inflate(R.menu.menu_settings, menu); return true; }Os documentos afirmam: "Você deve retornar true para que o menu seja exibido; se você retornar false, ele não será exibido".
W3bshark 05/10
Além disso, gostaria de mencionar que essa abordagem é muito mais limpa do que a resposta aceita. Obrigado por compartilhar!
W3bshark 05/10
chamando invalidateOptionMenu () onCreateOptionMenu () chamado e eu manejo minhas condições em onCreateOptionMenu (). Obrigado pela boa resposta
user1912026 24/04
onPrepareOptionsMenu()deve ser usado para mostrar / ocultar a lógica, em vez de onCreateOptionsMenu()ser chamado apenas uma vez, para que não seja útil se você desejar alterar os itens do menu após a inicialização. Portanto, inflate no onCreate, mas mostre / oculte no onPrepare.
JCutting8
89

Sim.

  1. Você pode definir uma bandeira / condição.
  2. Ligue invalidateOptionsMenu()quando quiser ocultar a opção. Isso vai ligar onCreateOptionsMenu().
  3. Em onCreateOptionsMenu(), verifique a bandeira / condição e mostre ou oculte-a da seguinte maneira:
MenuItem item = menu.findItem(R.id.menu_Done);

if (flag/condition)) {
  item.setVisible(false); 
} else { }
suhas_sm
fonte
2
Não deveria ser em invalidateOptionsMenuvez de invalidateOptions?
Razz 4/15
3
Se você tornar sua bandeira um valor booleano, basta definir a visibilidade do item para a bandeira (ou bandeira!), Se necessário. Então, item.setVisbility (! Flag); faz deste um forro sem condição if.
Jwehrle 31/05
onde está definida a variável "menu"?
Jonathan
É passado como um parâmetro paraonCreateOptionsMenu
suhas_sm
usar esse método significa que o item ainda consome espaço e você pode acabar com uma "lacuna" na interface do usuário onde o botão deve estar. Usar removeItem em onPrepareOptionsMenu () fará o truque.
JCutting8
39

Você pode chamar isso:

MenuItem item = menu.findItem(R.id.my_item);
item.setVisible(false);

Atualizar:

Verifique se o seu código não retorna nullpara itemou pode travar o aplicativo.

elias
fonte
usar esse método significa que o item ainda consome espaço e você pode acabar com uma "lacuna" na interface do usuário onde o botão deve estar. Usar removeItem em onPrepareOptionsMenu () fará o truque.
JCutting8
33

Eu estava procurando uma resposta com um pouco mais de contexto. Agora que eu descobri, vou adicionar essa resposta.

Botão Ocultar por padrão no menu xml

Por padrão, o botão de compartilhamento ficará oculto, conforme definido por android:visible="false".

insira a descrição da imagem aqui

main_menu.xml

<?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">

    <!-- hide share button by default -->
    <item
        android:id="@+id/menu_action_share"
        android:icon="@drawable/ic_share_white_24dp"
        android:visible="false"     
        android:title="Share"
        app:showAsAction="always"/>

    <item
        android:id="@+id/menu_action_settings"
        android:icon="@drawable/ic_settings_white_24dp"
        android:title="Setting"
        app:showAsAction="ifRoom"/>

</menu>

Mostrar botão no código

Mas o botão de compartilhamento pode opcionalmente ser mostrado com base em alguma condição.

insira a descrição da imagem aqui

MainActivity.java

public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main_menu, menu);
    MenuItem shareItem = menu.findItem(R.id.menu_action_share);

    // show the button when some condition is true
    if (someCondition) {        
        shareItem.setVisible(true);
    }

    return true;
}

Veja também

Suragch
fonte
onPrepareOptionsMenu () deve ser usado para mostrar / ocultar a lógica em vez de onCreateOptionsMenu (), pois é chamado apenas uma vez, de modo que não é útil se você deseja alterar os itens de menu após a inicialização. Portanto, inflate no onCreate, mas mostre / oculte no onPrepare e use invalidateOptionsMenu()para atualizar o menu.
JCutting8
24

não funcionou para mim. Eu tive que usar explicitamente onPrepareOptionsMenupara definir um item invisível.

Portanto, use onCreateOptionsMenupara criar o menu e onPrepareOptionsMenualterar a visibilidade, etc.

hotzen
fonte
11
Para mim, funcionou nos dois sentidos, mas com base nos documentos do Android onPrepareOptionsMenu parece o lugar certo para realizar este tipo de operação: "Prepare o menu de opções padrão da tela a ser exibido. Isso é chamado logo antes do menu ser exibido, toda vez que é exibido Você pode usar esse método para ativar / desativar itens com eficiência ou modificar dinamicamente o conteúdo ".
yuval 15/09/2015
Sim, isso é ideal. onPrepareOptionsMenu () deve ser usado para mostrar / ocultar a lógica em vez de onCreateOptionsMenu (), pois é chamado apenas uma vez, de modo que não é útil se você deseja alterar os itens de menu após a inicialização. Portanto, inflate no onCreate, mas mostre / oculte no onPrepare e use invalidateOptionsMenu()para atualizar o menu.
JCutting8
9

Inicialmente, defina a visibilidade do item de menu como false no arquivo de layout do menu, da seguinte maneira:

<?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:visible="false"
        android:id="@+id/action_do_something"
        android:title="@string/txt_do_something"
        app:showAsAction="always|withText"
        android:icon="@drawable/ic_done"/>
</menu>

Você pode simplesmente definir a visibilidade do item de menu como false no seu onCreateOptionsMenu () depois de aumentar o menu.

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    super.onCreateOptionsMenu(menu, inflater);
    inflater.inflate(menu,R.menu.menu);
    MenuItem item = menu.findItem(R.id.menuItemId);
    if (item != null){
        item.setVisible(false);
    }
}
Akhila
fonte
onCreateOptionsMenu não retorna um valor booleano. A solução funcionou perfeitamente embora.
13133 Joseph
8

Tente o seguinte:

MenuItem myitem = menu.findItem(R.id.my_item);
myitem.setVisible(false);
mohamad sheikhi
fonte
7

Isso funcionou para mim tanto na Atividade quanto no Fragmento

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    if (menu.findItem(R.id.action_messages) != null)
        menu.findItem(R.id.action_messages).setVisible(false);
}
Bala Vishnu
fonte
11
No meu caso, onPrepareOptionsMenu retorna booleano, não nulo.
CoolMind 03/02
6

A resposta P1r4nh4 funciona bem, apenas a simplifiquei usando um sinalizador booleano:

public int mState = 0; //at the top of the code
//where you want to trigger the hide action
mState = 1; // to hide or mState = 0; to show
invalidateOptionsMenu(); // now onCreateOptionsMenu(...) is called again
...

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    // inflate menu from xml
    MenuInflater inflater = getSupportMenuInflater();
    inflater.inflate(R.menu.settings, menu);

    if (mState == 1) //1 is true, 0 is false
    {
        //hide only option 2
            menu.getItem(2).setVisible(false);
    }
}
Hiram
fonte
2
Usando 0e 1não é um "sinalizador booleano", é pseudo-booleano. além disso, não há razão para usar um booleano real aqui.
Ingo Bürk
2
Além disso, você pode ter vários estados, não apenas um para ocultar e outro para mostrar. Dependendo da complexidade do seu aplicativo e da sua recusa em escrever novas atividades para os novos estados do aplicativo, você pode ter um estado SHOW_ALL, um estado HIDE_ALL, mas também um estado HIDE_EDIT ou HIDE_SHARE, caso queira ocultar certas partes do menu.
P1r4nh4
4

De acordo com o site oficial do desenvolvedor Android, o OnCreateOptionMenu (menu Menu) não é recomendado para alterar itens ou ícones de menu, visibilidade .. etc no Runtime.

Depois que o sistema chama onCreateOptionsMenu (), ele retém uma instância do Menu que você preenche e não chama o OnCreateOptionsMenu () novamente, a menos que o menu seja invalidado por algum motivo. No entanto, você deve usar onCreateOptionsMenu () apenas para criar o estado inicial do menu e não fazer alterações durante o ciclo de vida da atividade.

Se você deseja modificar o menu de opções com base nos eventos que ocorrem durante o ciclo de vida da atividade, é possível fazê-lo no método onPrepareOptionsMenu (). Esse método passa o objeto Menu como ele existe atualmente para que você possa modificá-lo, como adicionar, remover ou desativar itens. (Os fragmentos também fornecem um retorno de chamada onPrepareOptionsMenu ().) --Site oficial do AndroidDeveloper -

Como recomendado Você pode usar este método onOptionsItemSelected (Item do MenuItem) para rastrear as entradas do usuário.

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    int id = item.getItemId();

    if (id == R.id.edit) {
        Intent intent = new Intent(this, ExampleActivity.class);
        intent.putExtra(BUNDLE_KEY, mConnection);
        startActivityForResult(intent, PICK_CHANGE_REQUEST);
        return true;
    } else if (id == R.id.delete) {
        showDialog(this);
        return true;
    }

    return super.onOptionsItemSelected(item);
}

Se você precisar alterar os itens de menu no tempo de execução, use o menuPrepareOptions (menu Menu) para alterá-los

@Override
public boolean onPrepareOptionsMenu(Menu menu){

    if (Utils.checkNetworkStatus(ExampleActivity.this)) {
        menu.findItem(R.id.edit).setVisible(true);
        menu.findItem(R.id.delete).setVisible(true);
    }else {
        menu.findItem(R.id.edit).setVisible(false);
        menu.findItem(R.id.delete).setVisible(false);
    }
    return true;
} 
Chanaka Fernando
fonte
alguns itens estão sempre visíveis; portanto, quando eu, setVisible(false)para o item sempre visível, ele não desaparece até clicar nos três pontos (o próprio menu). Se eu usar nos itens reorganizar-se imediatamente, mas eles perdem suas ações (se eu clicar em qualquer item, ele não faz nada). invalidateOptionsMenu()onPrepareOptionsMenu
Aliton Oliveira 18/02/19
3

defina um valor para uma variável e chame invalidateOptionsMenu ();

por exemplo

    selectedid=arg2;
            invalidateOptionsMenu();


 public boolean onPrepareOptionsMenu(Menu menu) {

    if(selectedid==1){
        menu.findItem(R.id.action_setting).setVisible(false);
        menu.findItem(R.id.action_s2).setVisible(false);
        menu.findItem(R.id.action_s3).setVisible(false);
    }
    else{
        if(selectedid==2){
            menu.findItem(R.id.action_search).setVisible(false);
            menu.findItem(R.id.action_s4).setVisible(false);
            menu.findItem(R.id.action_s5).setVisible(false);
        }
    }
    return super.onPrepareOptionsMenu(menu);
}
Zacharia
fonte
alguns itens estão sempre visíveis; portanto, quando eu, setVisible(false)para o item sempre visível, ele não desaparece até clicar nos três pontos (o próprio menu). Se eu usar nos itens reorganizar-se imediatamente, mas eles perdem suas ações (se eu clicar em qualquer item, ele não faz nada). invalidateOptionsMenu()onPrepareOptionsMenu
Aliton Oliveira 18/02/19
3

Você pode usar toolbar.getMenu().clear();para ocultar todos os itens de menu de uma só vez

Ajeet Yadav
fonte
@Ajeet_Yadav existe uma maneira de tornar o menu visível depois que você o limpa?
Shawn
3

Ao definir a visibilidade de todos os itens no Menu, o menu da barra de aplicativos ou o menu excedente será Ocultar automaticamente

Exemplo

private Menu menu_change_language;

...

...

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    ...
    ...
    menu_change_language = menu;
    menu_change_language.findItem(R.id.menu_change_language)
           .setVisible(true);

    return super.onCreateOptionsMenu(menu);
}

Antes de ir para outro fragmento, use o código abaixo:

if(menu_change_language != null){                 
    menu_change_language.findItem(R.id.menu_change_language)
       .setVisible(false);
}
Hantash Nadeem
fonte
2

https://stackoverflow.com/a/21215280/466363 - respondido por Look Alterno e Sufian

  • ActivityCompat.invalidateOptionsMenu () não retorna callPrepareOptionsMenu (); basta atualizar o menu diretamente.
  • Meu someMethod () é chamado de vários lugares, mesmo antes de onCreateOptionsMenu (), então devo verificar mMenu! = Null.
  • deve funcionar usando a API 8

.

private Menu mMenu;
   @Override
   public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
       inflater.inflate(R.menu.track_fragment, menu);
       mMenu = menu;
       }
   ...
   private void someMethod() {
   ...
       if (mMenu != null) {
          MenuItem item = mMenu.findItem(R.id.new_track);
          if (item != null) {
               item.setVisible(false);
               ActivityCompat.invalidateOptionsMenu(this.getActivity());
           }
       }
   ...
   }
  • ActivityCompat.invalidateOptionsMenu () não retorna callPrepareOptionsMenu (); basta atualizar o menu diretamente.

  • Meu someMethod () é chamado de vários lugares, mesmo antes de onCreateOptionsMenu (), então devo verificar mMenu! = Null.

  • deve funcionar usando a API 8
Shimon Doodkin
fonte
2

Se você fez tudo como nas respostas acima, mas um item de menu ainda está visível, verifique se você faz referência ao recurso exclusivo . Por exemplo, em onCreateOptionsMenu ou onPrepareOptionsMenu

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    MenuItem menuOpen = menu.findItem(R.id.menu_open);
    menuOpen.setVisible(false);
}

Ctrl + Clique em R.id.menu_open e verifique se ele existe apenas em um arquivo de menu. Caso esse recurso já esteja sendo usado em qualquer lugar e carregado em uma atividade, ele tentará se esconder lá.

CoolMind
fonte
2

A melhor maneira de ocultar todos os itens em um menu com apenas um comando é usar "group" em seu menu xml. Basta adicionar todos os itens de menu que estarão no seu menu excedente dentro do mesmo grupo.

Neste exemplo, temos dois itens de menu que sempre serão exibidos (item regular e pesquisa) e três itens de estouro:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/someItemNotToHide1"
        android:title="ITEM"
        app:showAsAction="always" />

    <item
        android:id="@+id/someItemNotToHide2"
        android:icon="@android:drawable/ic_menu_search"
        app:showAsAction="collapseActionView|ifRoom"
        app:actionViewClass="android.support.v7.widget.SearchView"
        android:title="Search"/>

    <group android:id="@+id/overFlowItemsToHide">
    <item android:id="@+id/someID" 
    android:orderInCategory="1" app:showAsAction="never" />
    <item android:id="@+id/someID2" 
    android:orderInCategory="1" app:showAsAction="never" />
    <item android:id="@+id/someID3" 
    android:orderInCategory="1" app:showAsAction="never" />
    </group>
</menu>

Em sua atividade (de preferência em onCreateOptionsMenu), use o comando setGroupVisible para definir a visibilidade de todos os itens de menu como false ou true.

public boolean onCreateOptionsMenu(Menu menu) {
   menu.setGroupVisible(R.id.overFlowItems, false); // Or true to be visible
}

Se você deseja usar este comando em qualquer outro lugar da sua atividade, salve a classe de menu em local e sempre verifique se o menu é nulo, pois você pode executar antes de createOptionsMenu:

Menu menu;

public boolean onCreateOptionsMenu(Menu menu) {
       this.menu = menu;

}

public void hideMenus() {
       if (menu != null) menu.setGroupVisible(R.id.overFlowItems, false); // Or true to be visible       
}
Adriano Moutinho
fonte
1

Para aqueles que usam a biblioteca Appcompat: Se sua Atividade incluir subclasses ActionBarActivity, você poderá chamar supportInvalidateOptionsMenu ()

Visto aqui: https://stackoverflow.com/a/19649877/1562524

RuideraJ
fonte
1

Eu acho que uma abordagem melhor seria usar uma variável de membro para o menu, inicializá-la em onCreateOptionsMenu () e usar setVisible () depois, sem invalidar o menu de opções.

Catalin Clabescu
fonte
1

esse código funcionou para mim

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main_menu,menu);
    if (Application.sharedPreferences.getInt("type",1) == 2)
    {
        menuItem = menu.findItem(R.id.menu_travel_orders);
        menuItem.setVisible(false);
    }
    return super.onCreateOptionsMenu(menu);
}
Sai Gopi N
fonte
1

Essa abordagem funcionou para mim:

private  Menu thismenu;

if (condition)
{
   if(thismenu != null)
   {
       thismenu.findItem(R.id.menu_save).setVisible(true);
       Toast.makeText(ProfileActivity.this, 
    ""+thismenu.findItem(R.id.menu_save).getTitle(),
                Toast.LENGTH_SHORT).show();
   }else
   {
       thismenu.findItem(R.id.menu_save).setVisible(false);
   }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
   getMenuInflater().inflate(R.menu.profile_menu, menu);
   thismenu = menu;

   return true;
}
Babá da floresta
fonte
1

Você está tentando acessar um item de menu de uma atividade que não tem acesso ao escopo. A chamada para localizar o item de menu retornará nulo , porque a visualização não está vinculada nem à atividade nem ao layout você está chamando.

Os itens de menu são vinculados a itens como " Barra de Navegação ", que por sua vez são vinculados à atividade correspondente.

Portanto, inicialize essas visualizações em activity () e acesse os itens de menu dentro dessas visualizações.

Navigation navView;
navView = findViewById(R.id.navigationView);

MenuItem item = navView.getMenu().findItem(R.id.item_hosting);
item.setVisible(false);
VeeyaaR
fonte
1

usar invalidateOptionsMenu()

para ligar onPrepareOptionsMenu(menu: Menu?)

você deve usar onCreateOptionsMenu () apenas para criar o estado inicial do menu e não fazer alterações durante o ciclo de vida da atividade ...

Quando um evento ocorre e você deseja executar uma atualização de menu, você deve chamar invalidateOptionsMenu () para solicitar que o sistema chamePrepareOptionsMenu ().

https://developer.android.com/guide/topics/ui/menus

Dan Alboteanu
fonte
0

Android kotlin, oculte ou defina a visibilidade de um item de menu na barra de ação programaticamente.

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    val inflater = menuInflater
    inflater.inflate(R.menu.main_menu, menu)
    val method = menu.findItem(R.id.menu_method)
    method.isVisible = false //if want to show set true
    return super.onCreateOptionsMenu(menu)
}
Aftab Alam
fonte