page.title=Menus parent.title=Interface do usuário parent.link=index.html @jd:body
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 {@link android.view.Menu} para apresentar ações de usuário e outras opções em suas atividades.
Começando com Android 3.0 (API de nível 11), dispositivos Android não são mais necessários para fornecer um botão de Menu dedicado. Com esta alteração, os aplicativos do Android devem migrar de uma dependência no painel de menu 6 itens tradicional para fornecer uma barra de ação 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 baseia-se em APIs de {@link android.view.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:
Se estiver desenvolvendo para Android 2.3 ou anterior, os usuários podem revelar o painel do menu de opções pressionando o botão Menu.
No Android 3.0 ou em posteriores, os itens do menu de opções são apresentados pela barra de ação como uma combinação de itens de ação na tela e opções de estouro. A partir do Android 3.0, o botão Menu é censurado (alguns dispositivos não têm), então você deve migrar usando a barra de ação para fornecer acesso a ações e outras opções.
Consulte a seção Criação de um menu de opções.
Ao desenvolver para Android 3.0 ou posterior, você deve usar o modo de ação contextual para ativar as ações no conteúdo selecionado. Este modo 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.
Consulte a seção criar um menu pop-up.
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 {@link android.view.Menu}) na atividade, ou no fragmento.
Usar um recurso de menu é uma boa prática por alguns motivos:
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>
<menu>
deve ser o nódulo raiz para o arquivo e pode reter um ou mais elementos
<item>
e <group>
.<item>
<menu>
aninhado para criar um submenu.<group>
A seguir há 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:
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 {@code <menu>} como filho de um {@code <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 {@link android.view.MenuInflater#inflate(int,Menu) MenuInflater.inflate()}. Nas seções a seguir, você verá como inflar um menu para cada tipo de menu.
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:
Para obter mais informações sobre os itens de ação e outros comportamentos da barra de ação, consulte o guia Barra de ação.
Observação: Mesmo se não estiver desenvolvendo para Android 3.0 ou posteriores, é possível compilar seu próprio layout de barra de ação para obter um efeito semelhante. Para obter um exemplo de como é possível suportar versões mais antigas do Android com uma barra de ação, consulte o exemplo Compatibilidade da barra de ação .
É possível declarar itens para o menu de opções da subclasse {@link android.app.Activity} ou de uma subclasse {@link android.app.Fragment}. Se a atividade e os fragmentos declararem itens para o menu de opções, eles estarão combinados na IU. O item da atividade aparece primeiro, seguido 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 {@code android:orderInCategory} em cada {@code <item>} que precisar mover.
Para especificar o menu de opções para uma atividade, substitua {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} (os fragmentos fornecem o próprio retorno de chamada de {@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()}). Neste método , é possível inflar o recurso de menu (definido no XML) em um {@link android.view.Menu} fornecido no retorno de chamada. Por exemplo:
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = {@link android.app.Activity#getMenuInflater()}; inflater.inflate(R.menu.game_menu, menu); return true; }
Também é possível adicionar itens de menu usando {@link android.view.Menu#add(int,int,int,int) add()} e recuperar os itens com {@link android.view.Menu#findItem findItem()} para revisar as propriedades com APIs de {@link android.view.MenuItem}.
Caso tenha desenvolvido o aplicativo para Android 2.3.x e anteriores, o sistema chamará {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} para criar o menu de opções quando o usuário abrir o menu pela primeira vez. Caso tenha desenvolvido para Android 3.0 e posteriores, o sistema chama {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} ao iniciar a atividade para mostrar os itens para a barra de ação.
Quando o usuário seleciona um item para o menu de opções (incluindo os itens de ação na barra de ação), o sistema chama o método {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} da atividade. Este método passa o {@link android.view.MenuItem} selecionado. É possível identificar o item chamando {@link android.view.MenuItem#getItemId()}, que retorna o ID único para o item de menu (definido pelo atributo {@code android:id} no recurso de menu ou em um número inteiro dado ao método {@link android.view.Menu#add(int,int,int,int) add()}). É possível combinar este 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); } }
Ao lidar com um item de menu, retorne {@code true}. Se não lidar com o item de menu, você deverá chamar a implementação de superclasse de {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} (a implementação padrão retornará como falsa).
Se a atividade incluir fragmentos, o sistema chamará primeiro {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} para a atividade e, em seguida, para cada fragmento (na ordem em que cada fragmento foi adicionado) até um retornar como {@code true} ou até todos os fragmentos serem chamados.
Dica: o Android 3.0 adiciona a possibilidade de definir o comportamento do clique para um item de menu em XML, usando o atributo {@code 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 {@link android.view.MenuItem} — quando o sistema chamar este 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 {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} e {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}. Em seguida, estenda esta classe para cada atividade que deve compartilhar o mesmo menu de opções. Desta 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 {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} nesta atividade. Chame {@code super.onCreateOptionsMenu(menu)} para que os itens de menu originais sejam criados e, em seguida, adicione os novos itens de menu com {@link android.view.Menu#add(int,int,int,int) menu.add()}. Você também pode substituir o comportamento da superclasse para itens de menu individuais.
Depois que o sistema chamar {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()}, ele reterá uma instância do {@link android.view.Menu} que você populará e não chamará {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} novamente, a não ser que o menu seja invalidado por algum motivo. No entanto, você deve usar {@link android.app.Activity#onCreateOptionsMenu(Menu) 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 {@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}. Este método passa a você o objeto {@link android.view.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 {@link android.app.Fragment#onPrepareOptionsMenu onPrepareOptionsMenu()}.)
No Android 2.3.x e em anteriores, o sistema chamará {@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()} sempre que o usuário abrir o menu de opções (pressionar o botão Menu ).
No Android 3.0 e posteriores, avalia-se o menu de opções quanto a sempre estar aberto quando os itens de menu são apresentados na barra de ação. Quando um evento ocorre e você quer realizar uma atualização de menu, você deve chamar {@link android.app.Activity#invalidateOptionsMenu invalidateOptionsMenu()} para pedir que o sistema chame {@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}.
Observação: você nunca deve alterar os itens no menu de opções com base no {@link android.view.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 vistas não podem ter foco, então você nunca deve usar o foco como base para modificar os itens no menu de opções. Se quiser fornecer itens de menu que sejam sensíveis a contexto para um {@link android.view.View}, use um menu de contexto.
Um menu contextual oferece ações que afetam um item ou estrutura de contexto específica na IU. É possível fornecer um menu de contexto para qualquer vista, mas ele é geralmente usado para itens em um {@link android.widget.ListView}, {@link android.widget.GridView}, ou em outras coleções de vistas em que o usuário pode realizar ações diretas em cada item.
Há duas formas de fornecer ações contextuais:
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, então você deve retornar a um menu de contexto flutuante nestes dispositivos.
Para fornecer um menu de contexto flutuante:
Se a atividade usar {@link android.widget.ListView} ou {@link android.widget.GridView} e você quiser que cada item forneça o mesmo menu de contexto, registre todos os itens para um menu de contexto passando {@link android.widget.ListView} ou {@link android.widget.GridView} para {@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()}.
Quando a vista registrada receber um evento de clique longo, o sistema chamará o método {@link android.view.View.OnCreateContextMenuListener#onCreateContextMenu 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); }
{@link android.view.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 {@link android.view.View} que o usuário selecionou e um objeto {@link android.view.ContextMenu.ContextMenuInfo} que fornece informações adicionais sobre o item selecionado. Se sua atividade tiver várias vistas, em que cada uma forneça um menu de contexto diferente, você deve usar esses parâmetros para determinar qual menu de contexto deve ser inflado.
Quando o usuário selecionar um item de menu, o sistema chamará este 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 {@link android.view.MenuItem#getItemId()} consulta o ID para o item de menu selecionado, o qual pode ser atribuído a cada item de menu no XML usando o atributo {@code android:id}, como exibido na seção Definição de um menu em XML.
Ao lidar com um item de menu, retorne {@code 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á este retorno de chamada primeiro. Ao chamar a superclasse ao não lidar, 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é que {@code true} ou {@code false} seja retornado. (A implementação padrão para {@link android.app.Activity} e {@code android.app.Fragment} retorna {@code false}, então você deve sempre chamar a superclasse ao não tratar de um item de menu.)
O modo de ação contextual é uma implementação de sistema de {@link android.view.ActionMode} que direciona a interação do usuário a efetuar ações contextuais. Quando um usuário ativa este 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 este modo estiver ativo, o usuário pode 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 VOLTAR, ou seleciona a ação Pronto na lateral esquerda da barra.
Observação: a barra de ação contextual não é necessariamente associada à barra de ação. Elas operam de forma independente, apesar de a barra de ação contextual ocupar visualmente a posição da barra de ação.
Caso esteja desenvolvendo para Android 3.0 (API de nível 11) e posteriores, você deve usar o modo de ação contextual para apresentar ações contextuais, em vez de usar o menu de contexto flutuante.
Para oferecer vistas que fornecem ações contextuais, você deve invocar o modo de ação contextual sobre um dos eventos (ou ambos):
A maneira do aplicativo de invocar o modo de ação contextual e definir o comportamento para cada ação depende do seu projeto. Há basicamente dois projetos:
As seguintes seções descrevem a configuração necessária para cada cenário.
Caso queira invocar o modo de ação contextual somente quando o usuário selecionar vistas específicas, você deve:
Por exemplo:
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 {@link android.view.ActionMode} associado ao evento. É possível usar APIs de {@link android.view.ActionMode} para realizar várias alterações ao CAB, como revisar um título e um subtítulo com {@link android.view.ActionMode#setTitle setTitle()} e {@link android.view.ActionMode#setSubtitle setSubtitle()} (útil para indicar quantos itens são selecionados).
Observe também que os exemplos acima definem a variável {@code mActionMode} como nula quando o modo de ação é destruído. Na etapa a seguir, você verá como ela é inicializada e quão útil salvar a variável do membro na atividade ou no fragmento pode ser.
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 {@link android.app.Activity#startActionMode startActionMode()}, o sistema retorna o {@link android.view.ActionMode} criado. Ao salvar isto 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, {@link android.view.ActionMode} é usado para garantir que a instância {@link android.view.ActionMode} não seja recriada se já estiver ativa, verificando se o membro é nulo antes de iniciar o modo de ação.
Se tiver uma coleção de itens em um {@link android.widget.ListView} ou {@link android.widget.GridView} (ou outra extensão de {@link android.widget.AbsListView}) e quiser permitir que os usuários realizem ações de agrupamento, 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 {@link android.view.ActionMode#invalidate} request return false; } });
É isso. Agora, quando o usuário selecionar um item com um clique longo, o sistema chamará o método {@link android.widget.AbsListView.MultiChoiceModeListener#onCreateActionMode 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 {@link android.widget.AbsListView#setItemChecked setItemChecked()}.
Figura 4. Um menu pop-up no aplicativo do Gmail, ancorado ao botão de estouro no cando direito superior.
Um {@link android.widget.PopupMenu} é um menu modal ancorado a uma {@link android.view.View}. Ele aparece sob a vista de âncora se tiver espaço, ou sobre a vista. Ele é útil para:
Observação: Isto 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.
Observação: {@link android.widget.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:
Por exemplo, a seguir há um botão com o atributo {@link android.R.attr#onClick 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 posteriores, é possível combinar as duas linhas que inflam o menu com {@link android.widget.PopupMenu#inflate PopupMenu.inflate()}.
O menu é dispensado quando o usuário seleciona um item ou toca fora da área do menu. É possível ouvir o evento de dispensa usando {@link android.widget.PopupMenu.OnDismissListener}.
Para realizar uma ação quando o usuário seleciona um item de menu, você deve implementar a interface {@link android.widget.PopupMenu.OnMenuItemClickListener} e registrá-la com {@link android.widget.PopupMenu} chamando {@link android.widget.PopupMenu#setOnMenuItemClickListener setOnMenuItemclickListener()}. Quando o usuário seleciona um item, o sistema chama o retorno de chamada {@link android.widget.PopupMenu.OnMenuItemClickListener#onMenuItemClick 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; } }
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 {@code <item>} dentro de um elemento {@code <group>} no recurso de menu ou especificando um ID de grupo com o método {@link android.view.Menu#add(int,int,int,int) add()}.
Abaixo há 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 {@code android:showAsAction="ifRoom"} para cada item, eles aparecerão na barra de ação ou no estouro de ação.
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 {@code android:checkable} no elemento {@code <item>}, ou para um grupo inteiro com o atributo {@code android:checkableBehavior} no elemento {@code <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 {@code android:checkableBehavior} aceita:
É possível aplicar um estado marcado padrão a um item usando o atributo {@code android:checked} no elemento {@code <item>} e alterar o seu código com o método {@link android.view.MenuItem#setChecked(boolean) setChecked()}.
Quando um item marcável é selecionado, o sistema chama o respectivo método retorno de chamada do item selecionado (como {@link android.app.Activity#onOptionsItemSelected(MenuItem) 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 o seu estado automaticamente. É possível consultar o estado do item (como ele era antes do usuário selecioná-lo) com {@link android.view.MenuItem#isChecked()} e, em seguida, definir o estado marcado com {@link android.view.MenuItem#setChecked(boolean) 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.
Às vezes, você desejará que um item de menu inicie uma atividade usando uma {@link android.content.Intent} (se é uma atividade no seu ou em outro aplicativo). Quando você sabe qual intenção quer usar e tem um item de menu específico que deve iniciar a intenção, é possível executá-la com {@link android.app.Activity#startActivity(Intent) startActivity()} durante o método de retorno de chamada selecionado no item (como o retorno de chamada {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}).
No entanto, caso não tenha certeza de que o dispositivo do usuário contém um aplicativo que lida com a intenção, adicionar um item que o invoca resulta em um item de menu que não funciona, pois a intenção pode não se resolver em uma atividade. Para resolver isto, o Android permite que você adicione itens de menu dinamicamente ao seu menu quando encontra atividades no dispositivo que lidam com a intenção.
Para adicionar itens de menu com base nas atividades disponíveis que aceitam uma intenção:
Se não houver nenhum aplicativo instalado que satisfaça a intenção, nenhum item de menu será adicionado.
Observação: {@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} é usado para lidar com o elemento atualmente selecionado na tela. Portanto, ele deve ser usado apenas ao criar um menu em {@link android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo) 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 intenção correspondente à intenção definida,
um item de menu é adicionado, usando o valor no android:label
do filtro de intenção
como o título do item e o ícone do aplicativo como o ícone do item de menu. O método
{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
addIntentOptions()} retorna o número de itens de menu adicionados.
Observação: Ao chamar {@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[]) addIntentOptions()}, ele substitui todos os itens de menu no grupo do menu especificado no primeiro argumento.
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 intenção como normalmente faz, mas certificando-se de incluir os valores {@link android.content.Intent#CATEGORY_ALTERNATIVE} e/ou {@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} para a categoria do filtro de intenção. 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 intenção no documento Intenções e filtros de intenções.
Para obter um exemplo de aplicativo que usa esta técnica, consulte o código de exemplo do Bloco de notas.