Tutorial Android #7 – Menus e Mensagens

Padrão

Olá pessoal! Continuando com a nossa série sobre Android, hoje vamos ver como adicionar itens de menu (acessíveis pelo botão físico de menu do dispositivo) e mensagens informativas (anotações) para os itens listados na nossa Lista de Restaurantes.

O primeiro passo, então, é adicionarmos em nossa classe de modelo o campo anotações, do tipo String. Após os o campo mais o setter e getter, a nossa classe Restaurante ficará assim:

package net.rafaeltoledo.restaurante.model;

public class Restaurante {

	private String nome = "";
	private String endereco = "";
	private String tipo = "";
	private String anotacoes = "";

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getEndereco() {
		return endereco;
	}

	public void setEndereco(String endereco) {
		this.endereco = endereco;
	}

	public String getTipo() {
		return tipo;
	}

	public void setTipo(String tipo) {
		this.tipo = tipo;
	}

	public String getAnotacoes() {
		return anotacoes;
	}

	public void setAnotacoes(String anotacoes) {
		this.anotacoes = anotacoes;
	}

	@Override
	public String toString() {
		return getNome();
	}
}

Continuando, vamos agora adicionar o campo para as anotações em nosso arquivo main.xml. Antes do nó Button, adicione o campo:

<TableRow>
	<TextView android:text="Anotações:"/>
	<EditText android:id="@+id/anotacoes"
		android:singleLine="false"
		android:gravity="top"
		android:lines="2"
		android:scrollHorizontally="false"
		android:maxLines="2"
		android:maxWidth="200sp"/>
</TableRow>

Caso execute o aplicativo, o formulário terá essa aparência:

O próximo passo é criarmos o menu, e configurá-lo para ser exibido quando o usuário pressionar a tecla Menu do celular. Para isso, vamos criar um novo arquivo XML, chamado opcao.xml, colocando-o em res/menu. O arquivo terá o seguinte conteúdo:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
	<item android:id="@+id/anotacao"
	    android:title="Exibir Anotação"
	    android:icon="@drawable/anotacao"/>
</menu>

O ícone anotacao (anotacao.png) pode ser baixado no final do post, junto com o projeto.

Continuando, agora adicione o seguinte método a nossa classe ListaRestaurantes:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
	new MenuInflater(this).inflate(R.menu.opcao, menu);
	return super.onCreateOptionsMenu(menu);
}

Agora, ao pressionar a tecla Menu do celular, a opção definida será exibida a opção de menu que definimos.

Agora, vamos adicionar o controle sobre o botão, para que a anotação seja exibida quando o usuário selecionar o botão Exibir Anotação. A questão principal, é que para isso precisamos saber qual anotação devemos exibir. Para isso, vamos criar um controle para saber qual restaurante está selecionado.

Para começar, vamos adicionar um novo atributo à nossa classe ListaRestaurantes, chamado atual, que será inicializado em null.

Restaurante atual = null;

Após isso, nos métodos onSave() e onListClick(), em vez de utilizar a variável local r, vamos utilizar o atributo atual. Além disso, lembre-se de adicionar as referências também ao novo atributo (anotacoes) nestes métodos, e crie um atributo para ele, juntamente com nome, endereco e tipos.

Por fim, adicione a seguinte implementação do método onOptionsItemSelected(), lembrando do atalho Ctrl + Shift + O para corrigir as importações.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
	if (item.getItemId() == R.id.anotacao) {
		String mensagem = "Nenhum restaurante selecionado";

		if (atual != null) {
			mensagem = atual.getAnotacoes();
		}

		Toast.makeText(this, mensagem, Toast.LENGTH_LONG).show();

		return true;
	}

	return super.onOptionsItemSelected(item);
}

Agora, ao cadastrar um restaurante e ir para a listagem, experimente pressionar a tecla menu para ver o que acontece.

Pra quem perdeu alguma parte ou não conseguiu acompanhar, segue a listagem da classe ListaRestaurantes:

package net.rafaeltoledo.restaurante;

import java.util.ArrayList;
import java.util.List;

import net.rafaeltoledo.restaurante.model.Restaurante;
import android.app.TabActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.Toast;
import android.widget.TabHost.TabSpec;
import android.widget.TextView;

public class ListaRestaurantes extends TabActivity {

	List<Restaurante> listaRestaurantes = new ArrayList<Restaurante>();
	AdaptadorRestaurante adaptador = null;
	Restaurante atual = null;

	EditText nome = null;
	EditText endereco = null;
	EditText anotacoes = null;
	RadioGroup tipos = null;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		nome = (EditText) findViewById(R.id.nome);
		endereco = (EditText) findViewById(R.id.end);
		tipos = (RadioGroup) findViewById(R.id.tipos);

		Button salvar = (Button) findViewById(R.id.salvar);
		salvar.setOnClickListener(onSave);

		ListView lista = (ListView) findViewById(R.id.restaurantes);
		adaptador = new AdaptadorRestaurante();
		lista.setAdapter(adaptador);
		lista.setOnItemClickListener(onListClick);

		TabSpec descritor = getTabHost().newTabSpec("tag1");
		descritor.setContent(R.id.restaurantes);
		descritor.setIndicator("Lista", getResources().getDrawable(R.drawable.lista));
		getTabHost().addTab(descritor);

		descritor = getTabHost().newTabSpec("tag2");
		descritor.setContent(R.id.detalhes);
		descritor.setIndicator("Detalhes", getResources().getDrawable(R.drawable.restaurante));
		getTabHost().addTab(descritor);

		getTabHost().setCurrentTab(0);
	}

	private OnItemClickListener onListClick = new OnItemClickListener() {
		public void onItemClick(AdapterView<?> parent, View view, int position,
				long id) {
			atual = listaRestaurantes.get(position);
			nome.setText(atual.getNome());
			endereco.setText(atual.getEndereco());
			anotacoes.setText(atual.getAnotacoes());

			if (atual.getTipo().equals("rodizio")) {
				tipos.check(R.id.rodizio);
			} else if (atual.getTipo().equals("fast_food")) {
				tipos.check(R.id.fast_food);
			} else {
				tipos.check(R.id.a_domicilio);
			}

			getTabHost().setCurrentTab(1);
		}
	};

	private OnClickListener onSave = new OnClickListener() {

		public void onClick(View arg0) {
			atual = new Restaurante();
			EditText nome = (EditText) findViewById(R.id.nome);
			EditText endereco = (EditText) findViewById(R.id.end);
			EditText anotacoes = (EditText) findViewById(R.id.anotacoes);

			atual.setNome(nome.getText().toString());
			atual.setEndereco(endereco.getText().toString());
			atual.setAnotacoes(anotacoes.getText().toString());

			RadioGroup tipos = (RadioGroup) findViewById(R.id.tipos);

			switch (tipos.getCheckedRadioButtonId()) {
			case R.id.rodizio:
				atual.setTipo("rodizio");
				break;
			case R.id.fast_food:
				atual.setTipo("fast_food");
				break;
			case R.id.a_domicilio:
				atual.setTipo("a_domicilio");
				break;
			}

			adaptador.add(atual);
		}
	};

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		new MenuInflater(this).inflate(R.menu.opcao, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == R.id.anotacao) {
			String mensagem = "Nenhum restaurante selecionado";

			if (atual != null) {
				mensagem = atual.getAnotacoes();
			}

			Toast.makeText(this, mensagem, Toast.LENGTH_LONG).show();

			return true;
		}

		return super.onOptionsItemSelected(item);
	}

	class AdaptadorRestaurante extends ArrayAdapter<Restaurante> {
		AdaptadorRestaurante() {
			super(ListaRestaurantes.this, R.layout.linha,
					listaRestaurantes);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {

			View linha = convertView;
			ArmazenadorRestaurante armazenador = null;

			if (linha == null) {
				LayoutInflater inflater = getLayoutInflater();
				linha = inflater.inflate(R.layout.linha, parent, false);
				armazenador = new ArmazenadorRestaurante(linha);
				linha.setTag(armazenador);
			} else {
				armazenador = (ArmazenadorRestaurante) linha.getTag();
			}

			armazenador.popularFormulario(listaRestaurantes.get(position));

			return linha;
		}
	}

	static class ArmazenadorRestaurante {
		private TextView nome = null;
		private TextView endereco = null;
		private ImageView icone = null;

		ArmazenadorRestaurante(View linha) {
			nome = (TextView) linha.findViewById(R.id.titulo);
			endereco = (TextView) linha.findViewById(R.id.endereco);
			icone = (ImageView) linha.findViewById(R.id.icone);
		}

		void popularFormulario(Restaurante r) {
			nome.setText(r.getNome());
			endereco.setText(r.getEndereco());

			if (r.getTipo().equals("rodizio")) {
				icone.setImageResource(R.drawable.rodizio);
			} else if (r.getTipo().equals("fast_food")) {
				icone.setImageResource(R.drawable.fast_food);
			} else {
				icone.setImageResource(R.drawable.entrega);
			}
		}
	}
}

E se quiser, pode baixar o projeto aqui.

Até a próxima!