Criando menu de contexto no Android (Context Menu)
Na App que estou desenvolvendo para armazenar meus cursos realizados na Alura, fiz uma lista de cursos e listei alguns que realizei:
Observe que a cada vez que tocamos em um curso, ou seja, um item da lista, vamos direto para o link do curso. Porém, notei que o curso de MySQL eu ainda não concluí, ou seja, preciso deletar ele da lista. Como podemos fazer isso no Android?
Geralmente adicionamos um click listener para implementar um clique com uma ação desejada, como por exemplo, deletar o item da lista, mas, cada item da lista já contém listener de clique para acessar a URL do curso, ou seja, não faz sentido implementar um outro click listener sendo que já existe um.
Então qual é a nossa alternativa? Lembra que nos computadores temos o botão direito? Isso mesmo! Aquele botão que clicamos e ele nos da opções que podemos fazer.
Então, no Android temos algo muito similar ao botão direito que é o menu de contexto ou, tecnicamente, context menu. Mas como podemos implementá-lo?
Atualmente, na minha App, tenho a activity CursosActivity
:
public class CursosActivity extends AppCompatActivity {
private ListView cursos;
private List<Curso> listaDeCursos;
private CursoAdapter adapter;
@Override protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_cursos);
cursos = (ListView) findViewById(R.id.activity_cursos_lista);
listaDeCursos = pedeLista();
adapter = new CursoAdapter(this, listaDeCursos);
}
@Override protected void onResume() {
super.onResume();
cursos.setAdapter(adapter);
clickDaListView(); }
private void clickDaListView() {
//implementação do click da lista
}
private List<Curso> pedeLista() {
//faz uma pesquisa e retorna uma lista de cursos
}
}
A partir do objeto cursos
do tipo ListView
, podemos chamar o método setOnCreateContextMenuListener()
que nos permite criar um context menu para a ListView
:
@Override protected void onResume() {
super.onResume();
cursos.setAdapter(adapter);
cursos.setOnCreateContextMenuListener();
clickDaListView();
}
Porém, da mesma forma como vemos nos demais listener do Android, precisamos implementar a interface View.OnCreateContextMenuListener()
. Portanto, faremos a implementação utilizando o recurso de classe anônima:
cursos.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
@Override public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) { } });
A partir do parâmetro contextMenu
podemos criar opções para o nosso context menu utilizando o método add
:
cursos.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
@Override public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
contextMenu.add(Menu.NONE, 1, Menu.NONE, "deletar");
}
}
);
Note que enviamos 4 parâmetros:
- 1º parâmetro: Refere-se ao
groupId
. - 2º parâmetro: Nesse parâmetro enviamos o
ItemId
que é justamente o id do menu, ou seja, é por meio dele que identificaremos esse menu. - 3º parâmetro: Nele informamos o
order
, ou seja, a posição que queremos ordenar o menu. - 4º parâmetro: Indica o nome que será exibido para o menu.
Note que tanto no groupId
quanto no order
colocamos o valor Menu.NONE
. Essa constante equivale a 0 e significa que não queremos atribuir esses parâmetros. Em outras palavras, no código acima, criamos um menu com id
1 e nome "deletar"
. Vamos testá-lo?
Se rodarmos a nossa App, a princípio, nada mudou. Mas, se pressionarmos um item da lista:
Veja que o nosso menu aparece! O que acontece se tocarmos no menu? Nada! Afinal, não configuramos uma ação pra ele, certo? Faremos isso então! Porém, como podemos dar uma ação para um context menu? Simples! Basta sobrescrevemos o método onContextItemSelected
na CursosActivity
:
@Override public boolean onContextItemSelected(MenuItem item) {
return super.onContextItemSelected(item);
}
Observe que ele já nos retorna o valor super.onContextItemSelected(item)
que equivale ao valor true
. Mas o que isso significa? Quando retornamos true
, informamos que o click para esse menu, será consumido apenas por ele.
Qual é o nosso próximo passo? Precisamos verificar se a opção "deletar" foi escolhida, porém, como podemos fazer isso? O parâmetro item
corresponde ao item que foi clicado, ou seja, a partir dele podemos verificar o id
e, se for igual a 1, saberemos que é o menu deletar.
Podemos utilizar if
s e else
s, porém, já que sabemos o que esperamos, isto é, o id
1, utilizaremos o switch case
:
@Override public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 1:
}
return super.onContextItemSelected(item);
}
Agora precisamos implementar a funcionalidade para deletar o curso. Porém, qual curso deletaremos? Em outras palavras, precisamos pegar primeiro a posição do curso que queremos deletar. Para pegarmos informações do item que chamou o context menu, precisamos utilizar o método getMenuInfo()
do objeto item
:
@Override public boolean onContextItemSelected(MenuItem item) {
item.getMenuInfo(); //restante do código
}
Então atribuímos o retorno desse método para um objeto do tipo AdapterView.AdapterContextMenuInfo
:
@Override public boolean onContextItemSelected(MenuItem item) { AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); //restante do código
}
A partir do objeto menuInfo
podemos pegar a posição do item que chamou o context menu por meio do atributo position
:
@Override public boolean onContextItemSelected(MenuItem item) { AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position = menuInfo.position;
//restante do código }
Agora que temos a posição desejada, podemos deletar o curso! Porém, antes de implementar o código, criaremos o método deletar()
enviando a position
:
@Override public boolean onContextItemSelected(MenuItem item) { AdapterView.AdapterContextMenuInfo menuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position = menuInfo.position;
switch (item.getItemId()) {
case 1: deletar(position);
} return super.onContextItemSelected(item);
}
private void deletar(int position) { }
Para deletar um item da lista, basta apenas usarmos o remove()
da listaDeCursos
enviando a position
:
listaDeCursos.remove(position);
E então, notificamos o adapter
dizendo que a lista foi modificada por meio do método notifyDataSetChanged()
:
private void deletar(int position) {
listaDeCursos.remove(position);
adapter.notifyDataSetChanged();
}
Vamos testar o nosso código? Vejamos o resultado:
O curso de MySQL é deletado conforme o esperado!
Nesse post vimos o "botão direito" do Android, ou seja, o context menu. Implementamos dentro de uma ListView
e vimos que, por padrão, ele funciona a partir de um click longo, ou melhor, pressionando o item da lista. Por fim, vimos como podemos adicionar ações para cada item do context menu buscando pelo seu id
.
Já conhecia o context menu? Não? O que achou dele? Deixe seu comentário :)
Que tal aprender a desenvolver a sua App Android desde o zero? Aqui na Alura, temos diversos cursos online de Android onde ensinamos você a desenvolver a sua primeira App com os principais conceitos do início ao fim.