lightbulb_outline Help shape the future of the Google Play Console, Android Studio, and Firebase. Start survey

Menus

Menus são componentes comuns da interface do usuário em diversos tipos de aplicativos. Para fornecer uma experiência familiar e consistente ao usuário, você deve usar APIs de Menu para apresentar ações de usuário e outras opções em suas atividades.

Desde o Android 3.0 (API de nível 11), dispositivos Android não precisam mais fornecer um botão de Menu dedicado. Com essa alteração, os aplicativos Android devem migrar de uma dependência do painel de menu de 6 itens tradicional para fornecer uma barra de aplicativos para apresentar as ações comuns de usuário.

Apesar de o design e a experiência do usuário para alguns dos itens do menu terem passado por mudanças, a semântica para definir um conjunto de ações e opções ainda se baseia em APIs de Menu . Este guia mostra como criar os três tipos fundamentais de menus ou apresentações de ação em todas as versões do Android:

Menu de opções e barra de aplicativos
O menu de opções é a coleção principal de itens de menu para uma atividade. É onde se deve colocar as ações que têm impacto global no aplicativo, como "Buscar", "Escrever e-mail" e "Configurações".

Consulte a seção Criação de 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 realiza um clique longo em um elemento. Ele fornece ações que afetam o conteúdo selecionado ou a estrutura do contexto.

O modo de ação contextual exibe os itens de ação que afetam o conteúdo selecionado em uma barra no topo da tela e permite que o usuário selecione vários itens.

Consulte a seção Criação de menus contextuais.

Menu pop-up
Um menu pop-up exibe itens em uma lista vertical ancorada à exibição que apresentou o menu. É bom para fornecer ações adicionais relacionadas a conteúdo específico ou opções de fornecimento de uma segunda parte de um comando. As ações em um menu pop-up não devem afetar diretamente o conteúdo correspondente — é para isso que servem as ações contextuais. Preferivelmente, o menu pop-up serve para ações estendidas que relacionam as regiões de conteúdo na atividade.

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

Definição de um menu em XML

Para todos os tipos de menu, o Android fornece um formato XML padrão para definir os itens de menu. Em vez de criar um menu no código da atividade, você deve definir um menu e todos os seus itens em um recurso de menu XML. É possível, assim, inflar o recurso do menu (carregá-lo como um objeto Menu) na atividade ou no fragmento.

Usar um recurso de menu é uma boa prática por alguns motivos:

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

Para definir o 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 recipiente para os itens de menu. Um elemento <menu> deve ser o nodo raiz para o arquivo e pode reter 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 que você categorize itens de menu para que eles compartilhem propriedades como estado ativo e visibilidade. Para obter mais informações, consulte a seção Criação de grupos de menu.

Eis 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"
          android: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 ou o comportamento de um item. Os itens no menu acima incluem os seguintes atributos:

android:id
Um ID de recurso exclusivo do item. Ele permite que o aplicativo reconheça o item quando o usuário o seleciona.
android:icon
Uma referência a um desenhável 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
Especifica quando e como esse item deve aparecer como um item de ação na barra de aplicativos.

Esses são os atributos mais importantes que devem ser usados, mas há vários outros disponíveis. Para obter informações sobre todos os atributos compatíveis, consulte o documento Recurso de menu.

É possível adicionar um submenu a um item em qualquer menu (exceto a um submenu) adicionando um elemento <menu> como filho de um <item>. Os submenus são úteis quando o aplicativo tem várias funções que podem ser organizadas em tópicos, como itens em uma barra de menu do aplicativo do PC (arquivo, editar, visualizar etc.). Por 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 em sua atividade, você precisa inflar o recurso do menu (converter o recurso XML em um objeto programável) usando MenuInflater.inflate(). Nas seções a seguir, você verá como inflar um menu para cada tipo de menu.

Criação de um menu de opções

Figural 1. Menu de opções no navegador do Android 2.3.

O menu de opções é onde você deve incluir ações e outras opções que são relevantes para o contexto de atividade atual, como "Buscar", "Escrever e-mail" e "Configurações".

O local onde os itens no menu de opções aparecem na tela depende da versão em que o aplicativo foi desenvolvido:

  • Caso tenha desenvolvido o aplicativo para Android 2.3.x (API de nível 10) ou inferior, os conteúdos do menu de opções aparecerão na parte inferior da tela, quando o usuário pressionar o botão Menu, como mostrado na figura 1. Quando aberto, a primeira parte visível é o menu de ícones, que tem até seis itens de menu. Se o menu incluir mais de seis itens, o Android colocará o sexto item e o restante em um menu flutuante que o usuário poderá abrir selecionando Mais.
  • Se você desenvolveu o aplicativo para Android 3.0 (API de nível 11) ou superior, os itens do menu de opções estão disponíveis na barra de aplicativos. Por padrão, o sistema posiciona todos os itens nas ações adicionais, que o usuário pode revelar com o ícone de ações adicionais no lado direito da barra de aplicativos (ou pressionando o botão Menu no dispositivo, se disponível). Para ativar o acesso rápido a ações importantes, é possível promover alguns itens para aparecerem na barra de aplicativos adicionando android:showAsAction="ifRoom" aos elementos <item> correspondentes (veja a figura 2).

    Para obter mais informações sobre os itens de ação e outros comportamentos da barra de aplicativos, consulte a aula Adição da barra do aplicativo.

Figura 2. Barra de aplicativos do aplicativo Honeycomb Gallery, exibindo guias de navegação e um item de ação de câmera (além do botão de ações adicionais).

É possível declarar itens para o menu de opções da subclasse Activity ou de uma subclasse Fragment. Se a atividade e os fragmentos declararem itens para o menu de opções, eles estarão combinados na IU. Os itens da atividade aparecem primeiro, seguidos de cada um desses fragmentos na ordem em que são adicionados à atividade. Se necessário, é possível reorganizar os itens do menu com o atributo android:orderInCategory em cada <item> que você precisar mover.

Para especificar o menu de opções para uma atividade, modifique onCreateOptionsMenu() (os fragmentos fornecem o próprio retorno de chamada de onCreateOptionsMenu()). Neste método , é possível inflar o recurso de menu (definido no XML) em um Menu fornecido no retorno de chamada. Por exemplo:

@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 recuperar os itens com findItem() para revisar as propriedades com APIs de MenuItem.

Caso tenha desenvolvido o aplicativo para Android versão 2.3.x ou anterior, o sistema chamará onCreateOptionsMenu() para criar o menu de opções quando o usuário abrir o menu pela primeira vez. Caso tenha desenvolvido para Android versão 3.0 ou posterior, o sistema chamará onCreateOptionsMenu() ao iniciar a atividade para mostrar os itens para a barra de aplicativos.

Processamento de eventos de clique

Quando o usuário seleciona um item para o menu de opções (inclusive os itens de ação na barra de aplicativos), o sistema chama o método onOptionsItemSelected() da atividade. Esse método passa o MenuItem selecionado. É possível identificar o item chamando getItemId(), que retorna o ID único para o item de menu (definido pelo atributo android:id no recurso de menu ou em 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. Por exemplo:

@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 com sucesso, retorne true. Se não processar o item de menu, você deverá chamar a implementação de superclasse de onOptionsItemSelected() (a implementação padrão retornará falso).

Se a atividade contiver fragmentos, o sistema chamará primeiro onOptionsItemSelected() para a atividade e, em seguida, para cada fragmento (na ordem em que cada fragmento foi adicionado) até que um retorne true ou até chamar todos os fragmentos.

Dica: O Android 3.0 adiciona a possibilidade de definir o comportamento do on-click para um item de menu em XML usando o atributo android:onClick. O valor do atributo deve ser o nome de um método definido pela atividade usando o menu. O método deve ser público e aceitar um único parâmetro MenuItem — quando o sistema chamar esse método, ele passará o item de menu selecionado. Para obter mais informações e um exemplo, consulte o documento Recurso de menu.

Dica: Se o aplicativo contiver várias atividades e algumas delas fornecerem o mesmo menu de opções, considere criar uma atividade que não implemente nada exceto os métodos onCreateOptionsMenu() e onOptionsItemSelected(). Em seguida, estenda essa classe para cada atividade que deve compartilhar o mesmo menu de opções. Dessa maneira, é possível gerenciar um conjunto de códigos para lidar com ações de menu e cada classe descendente herda os comportamentos do menu. Se quiser adicionar itens de menu a uma das atividades descendentes, substitua onCreateOptionsMenu() nessa atividade. Chame super.onCreateOptionsMenu(menu) para a criação dos itens de menu originais e, em seguida, adicione novos itens de menu com menu.add(). Você também pode substituir o comportamento da superclasse para itens de menu individuais.

Alteração dos itens de menu em tempo de execução

Depois que o sistema chamar onCreateOptionsMenu(), ele reterá uma instância do Menu que você populará e não chamará onCreateOptionsMenu() novamente, a não ser que o menu seja invalidado por algum motivo. No entanto, você deve usar onCreateOptionsMenu() somente para criar o estado inicial do menu e não para realizar alterações 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, é possível fazê-lo no método onPrepareOptionsMenu(). Esse método passa a você o objeto Menu, já que ele existe para que seja possível modificá-lo, como com adição, remoção ou desativação de itens. (Os fragmentos também fornecem um retorno de chamada de onPrepareOptionsMenu()).

No Android versão 2.3.x ou posterior, o sistema chamará {@linkandroid.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()} sempre que o usuário abrir o menu de opções (pressionar o botão Menu).

No Android versão 3.0 ou posterior, o menu de opções é considerado sempre aberto quando os itens de menu são apresentados na barra de aplicativos. Quando um evento ocorre e você quer realizar uma atualização de menu, chame invalidateOptionsMenu() para pedir que o sistema chame onPrepareOptionsMenu().

Observação: nunca se deve alterar os itens no menu de opções com base na View atualmente em foco. Quando estiver no modo de toque (quando o usuário não está usando cursor de bola ou um teclado), as exibições não poderão ter foco. Portanto, você nunca deve usar o foco como base para modificar os itens no menu de opções. Se quiser fornecer itens de menu sensíveis ao contexto para um View, use um menu de contexto.

Criação de menus contextuais

Figura 3. Capturas de tela de um menu de contexto flutuante (esquerda) e a barra de ação contextual (direita).

Um menu contextual oferece ações que afetam um item ou estrutura de contexto específico na IU. É possível fornecer um menu de contexto para qualquer exibição, mas ele é geralmente usado para itens em uma ListView, GridView ou em outras coleções de exibiçõ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 realiza um clique longo (pressiona e segura) em uma exibiçã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. Esae modo é uma implementação de sistema de ActionMode que exibe uma barra de ação contextual no topo da tela com itens de ação que afetam os itens selecionados. Quando esse modo está ativo, os usuários podem realizar uma ação em vários itens por vez (se o aplicativo permitir).

Observação: O modo de ação contextual está disponível no Android 3.0 (API de nível 11) e em posteriores e é a técnica preferencial para exibir ações contextuais quando disponível. Se o aplicativo for compatível com versões mais antigas que a 3.0, vocêrá deve retornar a um menu de contexto flutuante nestes dispositivos.

Criação de um menu de contexto flutuante

Para fornecer um menu de contexto flutuante:

  1. Registre o View ao qual o menu de contexto deve estar associado chamando registerForContextMenu() e passe-o para View.

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

  2. Implemente o método onCreateContextMenu() em sua Activity ou Fragment.

    Quando a exibição registrada receber um evento de clique longo, o sistema chamará o método onCreateContextMenu(). É aqui que você define os itens de menu, geralmente inflando um recurso de menu. Por exemplo:

    @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 que você infle o menu de contexto de um recurso de menu. Os parâmetros do método de retorno de chamada incluem o View que o usuário selecionou e um objeto ContextMenu.ContextMenuInfo que fornece informações adicionais sobre o item selecionado. Se sua atividade tiver várias exibições, em que cada uma forneça um menu de contexto diferente, você deverá usar esses parâmetros para determinar qual menu de contexto deve ser inflado.

  3. Implemente onContextItemSelected().

    Quando o usuário selecionar um item de menu, o sistema chamará esse método para que você possa realizar a ação adequada. Por exemplo:

    @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 para o item de menu selecionado, que pode ser atribuído a cada item de menu no XML usando o atributo android:id, como exibido na seção Definição de um menu em XML.

    Quando processar um item de menu com sucesso, retorne true. Se não lidar com o item de menu, você deverá passar o item de menu para a implementação de superclasse. Se a atividade incluir fragmentos, ela receberá esse retorno de chamada primeiro. Ao chamar a superclasse quando não processada, o sistema passará o evento para o respectivo método de retorno de chamada em cada fragmento, um por vez (na ordem em que cada fragmento foi adicionado) até o retorno de true ou false. (A implementação padrão para Activity e android.app.Fragment retorna false. Portanto, você deve sempre chamar a superclasse quando não processada.)

Uso do modo de ação contextual

O modo de ação contextual é uma implementação de sistema de ActionMode que direciona a interação do usuário a efetuar ações contextuais. Quando um usuário ativa esse modo selecionando um item, uma barra de ação contextual aparece na parte superior da tela para apresentar as ações que o usuário pode realizar nos itens selecionados. Enquanto esse modo estiver ativo, o usuário poderá selecionar vários itens (se você permitir), desmarcar itens e continuar a navegar dentro da atividade (o tanto que você permitir). O modo de ação é desativado e a barra de ação contextual desaparece quando o usuário desmarca todos os itens, pressiona o botão BACK ou seleciona a ação Done na lateral esquerda da barra.

Observação: A barra de ação contextual não é necessariamente associada à barra de aplicativos. Elas operam de forma independente, apesar de a barra de ação contextual ocupar visualmente a posição da barra de aplicativos.

Para oferecer exibições que fornecem ações contextuais, você deve invocar o modo de ação contextual sobre um dos eventos (ou ambos):

  • O usuário realiza um clique longo na exibição.
  • O usuário seleciona uma caixa de seleção ou um componente de IU semelhante dentro da exibição.

Como o aplicativo invoca o modo de ação contextual e define o comportamento para cada ação depende do seu projeto. Há basicamente dois projetos:

  • Para ações contextuais em exibições arbitrárias individuais.
  • Para ações contextuais em lote em grupos de itens em uma ListView ou GridView (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.

Ativação do modo de ação contextual para exibições individuais

Caso queira invocar o modo de ação contextual somente quando o usuário selecionar exibições específicas, você deverá:

  1. Implementar a interface ActionMode.Callback. Em seus métodos de retorno de chamada, é possível especificar as ações da barra de ação contextual, responder aos eventos de clique em itens de ação e processar outros eventos de ciclo de vida do modo de ação.
  2. Chame startActionMode() quando quiser exibir a barra (como quando o usuário realiza cliques longos na visualização).

Por exemplo:

  1. Implementar a interface ActionMode.Callback:
    private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
    
        // Called when the action mode is created; startActionMode() was 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, but
        // may 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) {
            mActionMode = null;
        }
    };
    

    Observe que esses retornos de chamada de eventos são quase exatamente iguais aos retornos de chamada do menu de opções, exceto que cada um deles também passa o objeto ActionMode associado ao evento. É possível usar APIs de ActionMode para realizar várias alterações no CAB, como revisar o título e subtítulo com setTitle() e setSubtitle() (útil para indicar quantos itens são selecionados).

    Observe também que os exemplos acima definem a variável mActionMode como nula quando o modo de ação é destruído. Na etapa a seguir, você verá como ela é inicializada e como pode ser útil salvar a variável do membro na atividade ou no fragmento.

  2. Chame startActionMode() para ativar o modo de ação contextual quando apropriado, como em resposta a um clique longo em uma View:

    someView.setOnLongClickListener(new View.OnLongClickListener() {
        // Called when the user long-clicks on someView
        public boolean onLongClick(View view) {
            if (mActionMode != null) {
                return false;
            }
    
            // Start the CAB using the ActionMode.Callback defined above
            mActionMode = getActivity().startActionMode(mActionModeCallback);
            view.setSelected(true);
            return true;
        }
    });
    

    Ao chamar startActionMode(), o sistema retorna o ActionMode criado. Ao salvar isso em uma variável do membro, é possível realizar alterações na barra de ação contextual em resposta a outros eventos. No exemplo acima, 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.

Ativação de ações contextuais agrupadas em ListView ou GridView

Se tiver uma coleção de itens em uma ListView ou GridView (ou outra extensão de AbsListView) e quiser permitir que os usuários realizem ações em lote, você deve:

Por exemplo:

ListView listView = getListView();
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {

    @Override
    public void onItemCheckedStateChanged(ActionMode mode, int position,
                                          long id, boolean checked) {
        // Here you can do something when items are selected/de-selected,
        // such as update the title in the CAB
    }

    @Override
    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
        // Respond to clicks on the actions in the CAB
        switch (item.getItemId()) {
            case R.id.menu_delete:
                deleteSelectedItems();
                mode.finish(); // Action picked, so close the CAB
                return true;
            default:
                return false;
        }
    }

    @Override
    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
        // Inflate the menu for the CAB
        MenuInflater inflater = mode.getMenuInflater();
        inflater.inflate(R.menu.context, menu);
        return true;
    }

    @Override
    public void onDestroyActionMode(ActionMode mode) {
        // Here you can make any necessary updates to the activity when
        // the CAB is removed. By default, selected items are deselected/unchecked.
    }

    @Override
    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
        // Here you can perform updates to the CAB due to
        // an invalidate() request
        return false;
    }
});

Pronto. Agora, quando o usuário selecionar um item com um clique longo, o sistema chamará o método onCreateActionMode() e exibirá a barra de ação contextual com as ações especificadas. Enquanto a barra de ação contextual estiver visível, os usuários poderão selecionar itens adicionais.

Em alguns casos em que as ações contextuais fornecem itens de ação comuns, você pode querer adicionar uma caixa de seleção ou um elemento de IU semelhante que permite que os usuários selecionem itens, pois eles podem não descobrir o comportamento do clique longo. Quando um usuário seleciona a caixa de seleção, é possível invocar o modo de ação contextual definindo o respectivo item de lista para o estado marcado com setItemChecked().

Criação de um menu pop-up

Figura 4. Um menu pop-up no aplicativo do Gmail, ancorado ao botão adicional no canto superior direito.

Um PopupMenu é um menu modal ancorado a uma View. Ele aparece sob a exibição de âncora se tiver espaço, ou sobre a exibição. Ele é útil para:

  • Fornecer um menu de estilo de estouro para ações que se relacionam com o conteúdo específico (como cabeçalhos de e-mail do Gmail, exibidos na figura 4).

    Observação: Isso não é igual ao menu de contexto, que geralmente é usado para ações que afetam o conteúdo selecionado. Para ações que afetam o conteúdo selecionado, use o modo de ação contextual ou o menu de contexto flutuante.

  • Fornecer uma segunda parte de uma sentença de comando (como um botão marcado como "Add" que produz um menu pop-up com opções diferentes de "Add").
  • Fornecer um menu suspenso semelhante a Spinner que não retenha uma seleção persistente.

Observação: PopupMenu está disponível com a API de nível 11 ou posteriores.

Se definir o menu em XML, abaixo é exposto o modo de exibir o menu pop-up:

  1. Instancie um PopupMenu com seu construtor, que usa o Context do aplicativo atual e a View em que o menu deve estar ancorado.
  2. Use MenuInflater para inflar o recurso de menu no objeto Menuretornado por PopupMenu.getMenu().
  3. Chame PopupMenu.show().

Por exemplo, a seguir há um botão com o atributo android:onClick que exibe um menu pop-up:

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_overflow_holo_dark"
    android:contentDescription="@string/descr_overflow_button"
    android:onClick="showPopup" />

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

public void showPopup(View v) {
    PopupMenu popup = new PopupMenu(this, v);
    MenuInflater inflater = popup.getMenuInflater();
    inflater.inflate(R.menu.actions, popup.getMenu());
    popup.show();
}

Em APIs de nível 14 ou posterior, é possível combinar as duas linhas que inflam o menu com PopupMenu.inflate().

O menu é dispensado quando o usuário seleciona um item ou toca fora da área do menu. Para ouvir o evento de dispensa, use PopupMenu.OnDismissListener.

Processamento de eventos de clique

Para realizar uma ação quando o usuário seleciona um item de menu, você deve implementar a interface PopupMenu.OnMenuItemClickListener e registrá-la com o PopupMenu chamando setOnMenuItemclickListener(). Quando o usuário seleciona um item, o sistema chama o retorno de chamada onMenuItemClick() na interface.

Por exemplo:

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

Criação de grupos de menu

Um grupo de menu é uma coleção de itens de menu que compartilham certas peculiaridades. Com um grupo, é possível:

É 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().

Eis 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, é possível modificar as peculiaridades dos dois itens no grupo mencionando o ID do grupo e usando os métodos listados acima. O sistema também nunca separará os itens agrupados. Por exemplo: se você declarar android:showAsAction="ifRoom" para cada item, eles aparecerão na barra de ação ou nas ações adicionais.

Uso de itens de menu marcáveis

Figura 5. Captura de tela de um submenu com itens marcáveis.

Um menu como uma interface pode ser útil para ativar e desativar as opções, usar uma caixa de seleção para opções independentes ou botões de rádio para grupos de opções mutuamente exclusivas. A figura 5 mostra um submenu com itens marcáveis com botões de rádio.

Observação: Os itens de menu no menu de ícones (do menu de opções) não podem exibir uma caixa de seleção ou um botão de rádio. Caso escolha tornar marcáveis os itens no menu de ícones, você deverá indicar manualmente o estado marcado arrastando o ícone e/ou digitando sempre que o estado for alterado.

É 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 menu são marcáveis com um botão de rádio:

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

single
Somente um item do grupo pode ser marcado (botões de rádio)
all
Todos os itens podem ser marcados (caixas de seleção)
none
Nenhum item é marcável

Para aplicar um estado marcado padrão a um item, pode-se usar o atributo android:checked no elemento <item> e alterar seu código com o método setChecked().

Quando um item marcável é selecionado, o sistema chama o respectivo método retorno de chamada do item selecionado (como onOptionsItemSelected()). É aqui que você deve definir o estado da caixa de seleção, pois a caixa de seleção ou o botão de rádio não altera seu estado automaticamente. É possível consultar o estado do item (como ele era antes do usuário selecioná-lo) com isChecked() e, em seguida, definir o estado marcado com setChecked(). Por exemplo:

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

Caso você não defina o estado marcado desta maneira, o estado visível do item (a caixa de seleção ou o botão de rádio) não se alterará quando o usuário selecioná-lo. Quando o estado é definido, a atividade preserva o estado marcado do item para que, quando o usuário abrir o menu posteriormente, o estado marcado definido esteja visível.

Observação: os itens de menu marcáveis servem para serem usados somente em uma base por sessão e não são salvos quando o aplicativo é destruído. Caso tenha configurações de aplicativo que gostaria de salvar para o usuário, você deve armazenar os dados usando as preferências compartilhadas.

Adição de itens de menu com base em um intent

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

No entanto, caso não tenha certeza de que o dispositivo do usuário contém um aplicativo que lida com o intent, adicionar um item que o invoca resulta em um item de menu que não funciona, pois o intent pode não se resolver em uma atividade. Para resolver isso, o Android permite que você adicione itens de menu dinamicamente ao seu menu quando encontra atividades no dispositivo que lidam com o intent.

Para adicionar itens de menu com base nas atividades disponíveis que aceitam um intent:

  1. Defina o intent com a categoria CATEGORY_ALTERNATIVE e/ou CATEGORY_SELECTED_ALTERNATIVE, além de quaisquer outros requisitos.
  2. Chame Menu.addIntentOptions(). O Android procura um aplicativo que possa realizar o intent e adiciona-o ao seu menu.

Se não houver nenhum aplicativo instalado que satisfaça o intent, nenhum item de menu será adicionado.

Observação: CATEGORY_SELECTED_ALTERNATIVE é usado para lidar com o elemento atualmente selecionado na tela. Portanto, ele deve ser usado apenas ao criar um menu em onCreateContextMenu().

Por exemplo:

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

    // Create an Intent that describes the requirements to fulfill, to be included
    // in our 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 applications.
    menu.addIntentOptions(
         R.id.intent_group,  // Menu group to which new items will be 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 our 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 ao intent definida, um item de menu é adicionado, usando o valor no android:label do filtro de intent como o título do item e o ícone do aplicativo como o ícone do item de menu. O método addIntentOptions() retorna o número de itens de menu adicionados.

Observação: Ao chamar addIntentOptions(), ele modifica todos os itens de menu no grupo do menu especificado no primeiro argumento.

Permissão para a atividade ser adicionada a outros menus

Você pode também oferecer os serviços da sua atividade para outros aplicativos, para que o aplicativo possa ser incluído no menu de outros (revertendo as funções descritas acima).

Para ser incluído nos menus de outros aplicativos, você precisa definir um filtro de intent como normalmente faz, mas certificando-se de incluir os valores CATEGORY_ALTERNATIVE e/ou CATEGORY_SELECTED_ALTERNATIVE para a categoria do filtro de intent. Por 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 no documento Intents e filtros de intents.

Para obter um aplicativo de amostra que usa essa técnica, consulte o exemplo de código do Bloco de notas.