Adicionar menus

Teste o Compose
O Jetpack Compose é o kit de ferramentas de interface recomendado para Android. Aprenda a adicionar componentes no Compose.

Menus são um componente comum da interface do usuário em vários tipos de apps. Para oferecer uma experiência do usuário conhecida e consistente, use as APIs Menu para apresentar ações do usuário e outras opções nas suas atividades.

Uma imagem com um exemplo de menu flutuante
Figura 1. Um menu acionado por um toque no ícone, que aparece abaixo do ícone do menu flutuante.

Este documento mostra como criar os três tipos fundamentais de menus ou apresentações de ação em todas as versões do Android:

Menu "opções" e barra de apps
O menu "opções" é o conjunto principal de itens de menu para uma atividade. É onde você coloca ações que têm impacto global no app, como "Pesquisar", "Escrever e-mail" e "Configurações".

Consulte a seção Criar um menu de opções.

Modo de ação contextual e menu de contexto
Um menu de contexto é um menu flutuante que aparece quando o usuário toca em um elemento e o mantém pressionado. Ela fornece ações que afetam o conteúdo selecionado ou o frame de contexto.

O modo de ação contextual exibe ações necessárias que afetam o conteúdo selecionado em uma barra na parte superior da tela e permite que o usuário selecione vários itens.

Consulte a seção Criar um menu contextual.

Menu pop-up
Um menu pop-up mostra uma lista vertical de itens ancorados à visualização que invoca o menu. É bom para fornecer ações adicionais relacionadas a conteúdo específico ou opções para a segunda parte de um comando. As ações em um menu pop-up não afetam diretamente o conteúdo correspondente. É para isso que servem as ações contextuais. Em vez disso, o menu pop-up serve para ações estendidas relacionadas a regiões de conteúdo na atividade.

Consulte a seção Criar um menu pop-up.

Definir um menu em XML

Para todos os tipos de menu, o Android oferece um formato XML padrão para definir os itens de menu. Em vez de criar um menu no código da atividade, defina um menu e todos os itens dele em um recurso de menu XML. Em seguida, é possível inflar o recurso de menu, carregando-o como um objeto Menu, na atividade ou no fragmento.

Usar um recurso de menu é uma prática recomendada pelos seguintes motivos:

  • É mais fácil para visualizar a estrutura do menu em XML.
  • Ela separa o conteúdo do menu do código comportamental do app.
  • Ele permite criar configurações alternativas de menu para diferentes versões da plataforma, tamanhos de tela e outras configurações aproveitando o framework de recursos do app.

Para definir um menu, crie um arquivo XML dentro do diretório res/menu/ do projeto e crie o menu com os seguintes elementos:

<menu>
Define um Menu, que é um contêiner para os itens de menu. Um elemento <menu> precisa ser o nó raiz do arquivo e pode conter um ou mais elementos <item> e <group>.
<item>
Cria um MenuItem, que representa um único item em um menu. Esse elemento pode conter um elemento <menu> aninhado para criar um submenu.
<group>
Um contêiner invisível e opcional para os elementos <item>. Ele permite categorizar itens de menu para que eles compartilhem propriedades, como estado ativo e visibilidade. Para mais informações, consulte a seção Criar um grupo de menus.

Veja um exemplo de menu chamado game_menu.xml:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/new_game"
          android:icon="@drawable/ic_new_game"
          android:title="@string/new_game"
          app:showAsAction="ifRoom"/>
    <item android:id="@+id/help"
          android:icon="@drawable/ic_help"
          android:title="@string/help" />
</menu>

O elemento <item> é compatível com vários atributos que você pode usar para definir a aparência e o comportamento de um item. Os itens no menu anterior incluem os seguintes atributos:

android:id
Um ID de recurso exclusivo do item que permite que o app reconheça o item quando o usuário o seleciona.
android:icon
É uma referência a um drawable para usar como o ícone do item.
android:title
Uma referência a uma string para usar como o título do item.
android:showAsAction
A especificação de quando e como esse item aparece como um item de ação na barra de apps.

Esses são os atributos mais importantes que você usa, mas há muitos outros disponíveis. Para mais informações sobre todos os atributos compatíveis, consulte a documentação do recurso Menu.

É possível adicionar um submenu a um item em qualquer menu adicionando um elemento <menu> como filho de um <item>. Os submenus são úteis quando o app tem muitas funções que podem ser organizadas em tópicos, como itens na barra de menus de um app para PC, como File, Edit e View. Confira este exemplo:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/file"
          android:title="@string/file" >
        <!-- "file" submenu -->
        <menu>
            <item android:id="@+id/create_new"
                  android:title="@string/create_new" />
            <item android:id="@+id/open"
                  android:title="@string/open" />
        </menu>
    </item>
</menu>

Para usar o menu na sua atividade, _inflate_ o recurso de menu, convertendo o recurso XML em um objeto programável usando MenuInflater.inflate(). As seções a seguir mostram como inflar um menu para cada tipo de menu.

Criar um menu "opções"

O menu "opções", como o mostrado na Figura 1, é onde você inclui ações e outras opções que são relevantes para o contexto da atividade atual, como "Pesquisar", "Escrever e-mail" e "Configurações".

Uma imagem mostrando a barra de apps do app Planilhas Google
Figura 2. O app Planilhas Google, mostrando vários botões, incluindo o botão flutuante de ação.

É possível declarar itens para o menu "opções" da subclasse Activity ou Fragment. Se a atividade e os fragmentos declararem itens para o menu "opções", eles serão combinados na interface. Os itens da atividade aparecem primeiro, seguidos pelos de cada fragmento, na ordem em que os fragmentos são adicionados à atividade. Se necessário, é possível reordenar os itens de menu com o atributo android:orderInCategory em cada <item> que você precisa mover.

Para especificar o menu "opções" para uma atividade, modifique onCreateOptionsMenu(). Os fragmentos fornecem o próprio callback onCreateOptionsMenu(). Nesse método, é possível inflar o recurso de menu, definido no XML, para o Menu fornecido no callback. Isso é mostrado neste exemplo:

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    val inflater: MenuInflater = menuInflater
    inflater.inflate(R.menu.game_menu, menu)
    return true
}

Java

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

Também é possível adicionar itens de menu usando add() e extrair itens com findItem() para revisar as propriedades com APIs MenuItem.

Processar eventos de clique

Quando o usuário seleciona um item no menu de opções, incluindo as ações necessárias na barra de apps, o sistema chama o método onOptionsItemSelected() da atividade. Esse método transmite o MenuItem selecionado. Para identificar o item, chame getItemId(), que retorna o ID exclusivo do item de menu, definido pelo atributo android:id no recurso de menu ou com um número inteiro fornecido ao método add(). É possível combinar esse ID com itens de menu conhecidos para realizar a ação adequada.

Kotlin

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    // Handle item selection.
    return when (item.itemId) {
        R.id.new_game -> {
            newGame()
            true
        }
        R.id.help -> {
            showHelp()
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

Java

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection.
    switch (item.getItemId()) {
        case R.id.new_game:
            newGame();
            return true;
        case R.id.help:
            showHelp();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Quando processar um item de menu corretamente, retorne true. Se você não processar o item de menu, chame a implementação da superclasse de onOptionsItemSelected(). A implementação padrão retorna falso.

Se a atividade incluir fragmentos, o sistema chamará primeiro onOptionsItemSelected() para a atividade e, em seguida, para cada fragmento na ordem em que serão adicionados, até que um retorne true ou todos os fragmentos sejam chamados.

Mudar itens do menu durante a execução

Depois que o sistema chamar onCreateOptionsMenu(), ele manterá uma instância do Menu preenchido e não chamará onCreateOptionsMenu() novamente, a menos que o menu seja invalidado. No entanto, use onCreateOptionsMenu() apenas para criar o estado inicial do menu e não para fazer mudanças durante o ciclo de vida da atividade.

Caso queira modificar o menu de opções com base em eventos que ocorrem durante o ciclo de vida da atividade, use o método onPrepareOptionsMenu(). Esse método transmite o objeto Menu como ele existe atualmente para que você possa modificá-lo, como adicionando, removendo ou desativando itens. Os fragmentos também fornecem um callback onPrepareOptionsMenu().

O menu de opções é considerado sempre aberto quando os itens de menu são apresentados na barra de apps. Quando ocorrer um evento e você quiser realizar uma atualização de menu, chame invalidateOptionsMenu() para solicitar que o sistema chame onPrepareOptionsMenu().

Criar um menu contextual

Imagem que mostra um menu de contexto flutuante
Figura 3. Um menu de contexto flutuante.

Um menu contextual oferece ações que afetam um item ou frame de contexto específico na interface. É possível fornecer um menu de contexto para qualquer visualização, mas ele é mais usado para itens em uma RecylerView ou outras coleções de visualizações em que o usuário pode realizar ações diretas em cada item.

Há duas formas de fornecer ações contextuais:

  • Em um menu de contexto flutuante. Um menu aparece como uma lista flutuante de itens de menu, semelhante a uma caixa de diálogo, quando o usuário toca e mantém pressionada uma visualização que declara suporte para um menu de contexto. Os usuários podem realizar uma ação contextual em um item por vez.
  • No modo de ação contextual. Esse modo é uma implementação do sistema de ActionMode que exibe uma barra de ações contextual, ou CAB, na parte de cima da tela com ações necessárias que afetam os itens selecionados. Quando esse modo está ativo, os usuários podem realizar uma ação em vários itens ao mesmo tempo, se o app for compatível.

Criar um menu de contexto flutuante

Para fornecer um menu de contexto flutuante, faça o seguinte:

  1. Registre o View ao qual o menu de contexto está associado, chamando registerForContextMenu() e transmitindo View.

    Se a atividade usar um RecyclerView e você quiser que cada item forneça o mesmo menu de contexto, registre todos os itens de um menu de contexto transmitindo RecyclerView para registerForContextMenu().

  2. Implemente o método onCreateContextMenu() na Activity ou no Fragment.

    Quando a visualização registrada recebe um evento de tocar e pressionar, o sistema chama seu método onCreateContextMenu(). É aqui que você define os itens de menu, geralmente inflando um recurso de menu, como no exemplo a seguir:

    Kotlin

        override fun onCreateContextMenu(menu: ContextMenu, v: View,
                                menuInfo: ContextMenu.ContextMenuInfo) {
            super.onCreateContextMenu(menu, v, menuInfo)
            val inflater: MenuInflater = menuInflater
            inflater.inflate(R.menu.context_menu, menu)
        }
        

    Java

        @Override
        public void onCreateContextMenu(ContextMenu menu, View v,
                                        ContextMenuInfo menuInfo) {
            super.onCreateContextMenu(menu, v, menuInfo);
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.context_menu, menu);
        }
        

    MenuInflater permite inflar o menu de contexto a partir de um recurso de menu. Os parâmetros do método de callback incluem o View que o usuário seleciona e um objeto ContextMenu.ContextMenuInfo que fornece mais informações sobre o item selecionado. Se a atividade tiver várias visualizações, e cada uma delas fornecer um menu de contexto diferente, você poderá usar esses parâmetros para determinar qual menu de contexto será inflado.

  3. Implemente onContextItemSelected(), conforme mostrado no exemplo abaixo. Quando o usuário seleciona um item de menu, o sistema chama esse método para que você possa realizar a ação adequada.

    Kotlin

        override fun onContextItemSelected(item: MenuItem): Boolean {
            val info = item.menuInfo as AdapterView.AdapterContextMenuInfo
            return when (item.itemId) {
                R.id.edit -> {
                    editNote(info.id)
                    true
                }
                R.id.delete -> {
                    deleteNote(info.id)
                    true
                }
                else -> super.onContextItemSelected(item)
            }
        }
        

    Java

        @Override
        public boolean onContextItemSelected(MenuItem item) {
            AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
            switch (item.getItemId()) {
                case R.id.edit:
                    editNote(info.id);
                    return true;
                case R.id.delete:
                    deleteNote(info.id);
                    return true;
                default:
                    return super.onContextItemSelected(item);
            }
        }
        

    O método getItemId() consulta o ID do item de menu selecionado, que você atribui a cada item de menu em XML usando o atributo android:id, conforme mostrado em Definir um menu em XML.

    Quando processar um item de menu corretamente, retorne true. Se você não gerenciar o item de menu, transmita-o para a implementação da superclasse. Se a atividade incluir fragmentos, ela receberá esse callback primeiro. Ao chamar a superclasse quando não processada, o sistema transmite o evento para o respectivo método de callback em cada fragmento, um por vez, na ordem em que cada fragmento é adicionado, até que true ou false sejam retornados. As implementações padrão para Activity e android.app.Fragment retornam false. Portanto, sempre chame a superclasse quando não processada.

Usar o modo de ação contextual

O modo de ação contextual é uma implementação do sistema de ActionMode que direciona a interação do usuário para realizar ações contextuais. Quando um usuário ativa esse modo selecionando um item, uma barra de ações contextual é exibida na parte superior da tela para apresentar as ações que o usuário pode realizar nos itens selecionados. Enquanto esse modo estiver ativado, o usuário poderá selecionar vários itens, se o app oferecer suporte, além de desmarcar itens e continuar navegando dentro da atividade. O modo de ação é desativado e a barra de ação contextual desaparece quando o usuário desmarca todos os itens, toca no botão "Voltar" ou na ação Done no lado esquerdo da barra.

Para visualizações que fornecem ações contextuais, você geralmente invoca o modo de ação contextual quando um ou ambos os eventos abaixo ocorrem:

  • O usuário toca na visualização e mantém pressionada.
  • O usuário seleciona uma caixa de seleção ou um componente de IU semelhante dentro da visualização.

A forma como o app invoca o modo de ação contextual e define o comportamento para cada ação depende do seu design. Há dois designs:

  • Para ações contextuais em visualizações arbitrárias individuais
  • Para ações contextuais em lote em grupos de itens em uma RecyclerView, permitindo que o usuário selecione vários itens e realize uma ação em todos eles.

As seguintes seções descrevem a configuração necessária para cada cenário.

Ativar o modo de ação contextual para visualizações individuais

Se você quiser invocar o modo de ação contextual somente quando o usuário selecionar visualizações específicas, faça o seguinte:

  1. Implemente a interface ActionMode.Callback, conforme mostrado no exemplo abaixo. Nos métodos de callback, é possível especificar as ações para a barra de ação contextual, responder a eventos de clique em ações necessárias e processar outros eventos de ciclo de vida para o modo de ação.

    Kotlin

        private val actionModeCallback = object : ActionMode.Callback {
            // Called when the action mode is created. startActionMode() is called.
            override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
                // Inflate a menu resource providing context menu items.
                val inflater: MenuInflater = mode.menuInflater
                inflater.inflate(R.menu.context_menu, menu)
                return true
            }
    
            // Called each time the action mode is shown. Always called after
            // onCreateActionMode, and might be called multiple times if the mode
            // is invalidated.
            override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
                return false // Return false if nothing is done
            }
    
            // Called when the user selects a contextual menu item.
            override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
                return when (item.itemId) {
                    R.id.menu_share -> {
                        shareCurrentItem()
                        mode.finish() // Action picked, so close the CAB.
                        true
                    }
                    else -> false
                }
            }
    
            // Called when the user exits the action mode.
            override fun onDestroyActionMode(mode: ActionMode) {
                actionMode = null
            }
        }
        

    Java

        private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
    
            // Called when the action mode is created. startActionMode() is called.
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                // Inflate a menu resource providing context menu items.
                MenuInflater inflater = mode.getMenuInflater();
                inflater.inflate(R.menu.context_menu, menu);
                return true;
            }
    
            // Called each time the action mode is shown. Always called after
            // onCreateActionMode, and might be called multiple times if the mode
            // is invalidated.
            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return false; // Return false if nothing is done.
            }
    
            // Called when the user selects a contextual menu item.
            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
               switch (item.getItemId()) {
                    case R.id.menu_share:
                        shareCurrentItem();
                        mode.finish(); // Action picked, so close the CAB.
                        return true;
                    default:
                        return false;
                }
            }
    
            // Called when the user exits the action mode.
            @Override
            public void onDestroyActionMode(ActionMode mode) {
                actionMode = null;
            }
        };
        

    Esses callbacks de evento são quase exatamente iguais aos callbacks do menu "opções", exceto que cada um deles também transmite o objeto ActionMode associado ao evento. Você pode usar APIs ActionMode para fazer várias mudanças no CAB, como revisar o título e o subtítulo com setTitle() e setSubtitle(), o que é útil para indicar quantos itens são selecionados.

    O exemplo anterior define a variável actionMode como null quando o modo de ação é destruído. Na próxima etapa, veja como ela é inicializada e como pode ser útil salvar a variável do membro na atividade ou no fragmento.

  2. Chame startActionMode() quando quiser mostrar a barra, por exemplo, quando o usuário tocar na visualização e mantê-la pressionada.

    Kotlin

        someView.setOnLongClickListener { view ->
            // Called when the user performs a touch & hold on someView.
            when (actionMode) {
                null -> {
                    // Start the CAB using the ActionMode.Callback defined earlier.
                    actionMode = activity?.startActionMode(actionModeCallback)
                    view.isSelected = true
                    true
                }
                else -> false
            }
        }
        

    Java

        someView.setOnLongClickListener(new View.OnLongClickListener() {
            // Called when the user performs a touch & hold on someView.
            public boolean onLongClick(View view) {
                if (actionMode != null) {
                    return false;
                }
    
                // Start the CAB using the ActionMode.Callback defined earlier.
                actionMode = getActivity().startActionMode(actionModeCallback);
                view.setSelected(true);
                return true;
            }
        });
        

    Quando você chama startActionMode(), o sistema retorna o ActionMode criado. Ao salvar isso em uma variável de membro, é possível fazer alterações na barra de ação contextual em resposta a outros eventos. No exemplo anterior, o ActionMode é usado para garantir que a instância ActionMode não seja recriada se já estiver ativa, verificando se o membro é nulo antes de iniciar o modo de ação.

Criar um menu pop-up

Imagem que mostra um menu pop-up no app Gmail, ancorado ao botão flutuante no canto superior direito.
Figura 4. Um menu pop-up no app Gmail, ancorado ao botão flutuante no canto superior direito.

Um PopupMenu é um menu modal ancorado a uma View. Ele aparece abaixo da visualização da âncora, se houver espaço. Caso contrário, ele aparece acima da visualização. Ele é útil para o seguinte:

  • Fornecer um menu de estilo flutuante para ações relacionadas a um conteúdo específico, como os cabeçalhos de e-mail do Gmail, mostrados na figura 4.
  • Fornecer uma segunda parte de uma frase de comando, como um botão marcado como Add que produz um menu pop-up com diferentes opções de Add.
  • Fornecer um menu semelhante a um Spinner que não retenha uma seleção persistente.

Se você definir seu menu em XML, veja como mostrar o menu pop-up:

  1. Instancie um PopupMenu com o respectivo construtor, que usa o Context do app atual e o View ao qual o menu está ancorado.
  2. Use MenuInflater para inflar o recurso de menu no objeto Menu retornado por PopupMenu.getMenu().
  3. Chame o método PopupMenu.show().

Por exemplo, veja um botão que mostra um menu pop-up:

<ImageButton
    android:id="@+id/dropdown_menu"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:contentDescription="@string/descr_overflow_button"
    android:src="@drawable/arrow_drop_down" />

A atividade pode então exibir o menu pop-up desta forma:

Kotlin

findViewById<ImageButton>(R.id.dropdown_menu).setOnClickListener {
    val popup = PopupMenu(this, it)
    val inflater: MenuInflater = popup.menuInflater
    inflater.inflate(R.menu.actions, popup.menu)
    popup.show()
}

Java

findViewById(R.id.dropdown_menu).setOnClickListener(v -> {
    PopupMenu popup = new PopupMenu(this, v);
    popup.getMenuInflater().inflate(R.menu.actions, popup.getMenu());
    popup.show();
});

O menu é dispensado quando o usuário seleciona um item ou toca fora da área do menu. É possível detectar o evento de dispensa usando PopupMenu.OnDismissListener.

Processar eventos de clique

Para realizar uma ação quando o usuário seleciona um item de menu, implemente a interface PopupMenu.OnMenuItemClickListener e registre-a com seu PopupMenu chamando setOnMenuItemclickListener(). Quando o usuário seleciona um item, o sistema chama o callback onMenuItemClick() na interface.

Isso é mostrado neste exemplo:

Kotlin

fun showMenu(v: View) {
    PopupMenu(this, v).apply {
        // MainActivity implements OnMenuItemClickListener.
        setOnMenuItemClickListener(this@MainActivity)
        inflate(R.menu.actions)
        show()
    }
}

override fun onMenuItemClick(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.archive -> {
            archive(item)
            true
        }
        R.id.delete -> {
            delete(item)
            true
        }
        else -> false
    }
}

Java

public void showMenu(View v) {
    PopupMenu popup = new PopupMenu(this, v);

    // This activity implements OnMenuItemClickListener.
    popup.setOnMenuItemClickListener(this);
    popup.inflate(R.menu.actions);
    popup.show();
}

@Override
public boolean onMenuItemClick(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.archive:
            archive(item);
            return true;
        case R.id.delete:
            delete(item);
            return true;
        default:
            return false;
    }
}

Criar um grupo de menus

Um grupo de menu é uma coleção de itens de menu que compartilham certas peculiaridades. Com um grupo, você pode fazer o seguinte:

É possível criar um grupo aninhando elementos <item> dentro de um elemento <group> no recurso de menu ou especificando um ID de grupo com o método add().

Veja um exemplo de recurso de menu que inclui um grupo:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_save"
          android:icon="@drawable/menu_save"
          android:title="@string/menu_save" />
    <!-- menu group -->
    <group android:id="@+id/group_delete">
        <item android:id="@+id/menu_archive"
              android:title="@string/menu_archive" />
        <item android:id="@+id/menu_delete"
              android:title="@string/menu_delete" />
    </group>
</menu>

Os itens que estão no grupo aparecem no mesmo nível que o primeiro item. Todos os três itens no menu são irmãos. No entanto, você pode modificar as características dos dois itens no grupo referenciando o ID do grupo e usando os métodos anteriores. O sistema também nunca separa os itens agrupados. Por exemplo, se você declarar android:showAsAction="ifRoom" para cada item, os dois vão aparecer na barra de ações ou no estouro de ações.

Usar itens de menu marcáveis

Figura 5. Um submenu com itens marcáveis.

Um menu pode ser útil como uma interface para ativar e desativar opções, usar uma caixa de seleção para opções independentes ou botões de opção para grupos de opções mutuamente exclusivas. A Figura 5 mostra um submenu com itens que podem ser marcados com botões de opção.

É possível definir o comportamento marcável para itens individuais de menu usando o atributo android:checkable no elemento <item> ou para um grupo inteiro com o atributo android:checkableBehavior no elemento <group>. Por exemplo, todos os itens neste grupo de menus são marcáveis com um botão de opção:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item android:id="@+id/red"
              android:title="@string/red" />
        <item android:id="@+id/blue"
              android:title="@string/blue" />
    </group>
</menu>

O atributo android:checkableBehavior aceita uma das seguintes opções:

single
Somente um item do grupo pode ser marcado, resultando em botões de opção.
all
Todos os itens podem ser marcados, resultando em caixas de seleção.
none
Nenhum item pode ser marcado.

É possível aplicar um estado marcado padrão a um item usando o atributo android:checked no elemento <item> e mudar o código dele com o método setChecked().

Quando um item marcável é selecionado, o sistema chama o respectivo método de callback do item selecionado, como onOptionsItemSelected(). É aqui que você define o estado da caixa de seleção, porque uma caixa de seleção ou um botão de opção não muda de estado automaticamente. É possível consultar o estado atual do item (como ele era antes de o usuário selecioná-lo) com isChecked() e definir o estado marcado com setChecked(). Isso é mostrado neste exemplo:

Kotlin

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.vibrate, R.id.dont_vibrate -> {
            item.isChecked = !item.isChecked
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

Java

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.vibrate:
        case R.id.dont_vibrate:
            if (item.isChecked()) item.setChecked(false);
            else item.setChecked(true);
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Se você não definir o estado marcado dessa maneira, o estado visível da caixa de seleção ou do botão de opção não vai mudar quando o usuário o selecionar. Quando o estado é definido, a atividade preserva o estado marcado do item para que, quando o usuário abrir o menu mais tarde, o estado marcado definido fique visível.

Adicionar itens de menu com base em uma intent

Às vezes, você quer que um item de menu inicie uma atividade usando uma Intent, seja uma atividade no seu app ou em outro. Quando você sabe qual é a intent que quer usar e tem um item de menu específico que a inicia, é possível executá-la com startActivity() durante o método de callback adequado selecionado no item, como o callback onOptionsItemSelected().

No entanto, se você não tiver certeza de que o dispositivo do usuário contém um app que processa a intent, a adição de um item de menu que a invoca pode resultar em um item de menu que não funciona, porque a intent pode não ser resolvida em uma atividade. Para resolver esse problema, o Android permite adicionar itens de menu ao seu menu de forma dinâmica quando ele encontra atividades no dispositivo que processam a intent.

Para adicionar itens de menu com base nas atividades disponíveis que aceitam uma intent, faça o seguinte:

  1. Defina uma intent com a categoria CATEGORY_ALTERNATIVE ou CATEGORY_SELECTED_ALTERNATIVE, ou ambas, além de outros requisitos.
  2. Chame Menu.addIntentOptions(). Em seguida, o Android procura apps que possam realizar a intent e os adiciona ao seu menu.

Se não houver apps instalados que satisfaçam a intent, nenhum item de menu será adicionado.

Isso é mostrado neste exemplo:

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    super.onCreateOptionsMenu(menu)

    // Create an Intent that describes the requirements to fulfill, to be
    // included in the menu. The offering app must include a category value
    // of Intent.CATEGORY_ALTERNATIVE.
    val intent = Intent(null, dataUri).apply {
        addCategory(Intent.CATEGORY_ALTERNATIVE)
    }

    // Search and populate the menu with acceptable offering apps.
    menu.addIntentOptions(
            R.id.intent_group,  // Menu group to which new items are added.
            0,                  // Unique item ID (none).
            0,                  // Order for the items (none).
            this.componentName, // The current activity name.
            null,               // Specific items to place first (none).
            intent,             // Intent created above that describes the requirements.
            0,                  // Additional flags to control items (none).
            null)               // Array of MenuItems that correlate to specific items (none).

    return true
}

Java

@Override
public boolean onCreateOptionsMenu(Menu menu){
    super.onCreateOptionsMenu(menu);

    // Create an Intent that describes the requirements to fulfill, to be
    // included in the menu. The offering app must include a category value
    // of Intent.CATEGORY_ALTERNATIVE.
    Intent intent = new Intent(null, dataUri);
    intent.addCategory(Intent.CATEGORY_ALTERNATIVE);

    // Search and populate the menu with acceptable offering apps.
    menu.addIntentOptions(
         R.id.intent_group,         // Menu group to which new items are added.
         0,                         // Unique item ID (none).
         0,                         // Order for the items (none).
         this.getComponentName(),   // The current activity name.
         null,                      // Specific items to place first (none).
         intent,                    // Intent created above that describes the requirements.
         0,                         // Additional flags to control items (none).
         null);                     // Array of MenuItems that correlate to specific items (none).

    return true;
}

Para cada atividade encontrada que fornece um filtro de intent correspondente à intent definida, um item de menu é adicionado, usando o valor no android:label do filtro de intent como o título do item de menu e o ícone do app como o ícone do item de menu. O método addIntentOptions() retorna o número de itens de menu adicionados.

Permitir que sua atividade seja adicionada a outros menus

Você pode oferecer os serviços da sua atividade a outros apps para que ele possa ser incluído no menu de outros, revertendo os papéis descritos anteriormente.

Para ser incluído em outros menus do app, defina um filtro de intent como de costume, mas inclua os valores CATEGORY_ALTERNATIVE ou CATEGORY_SELECTED_ALTERNATIVE, ou ambos, para a categoria de filtro de intent. Isso é mostrado neste exemplo:

<intent-filter label="@string/resize_image">
    ...
    <category android:name="android.intent.category.ALTERNATIVE" />
    <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
    ...
</intent-filter>

Leia mais sobre a criação de filtros de intent em Intents e filtros de intent.