Tutorial Android #5 – Aprimorando a Lista

Padrão

Olá pessoal! Prosseguindo com o tutorial sobre Android, vamos hoje aprimorar o nosso formulário. No último post, os Restaurantes, ao serem adicionados, eram listados na parte superior da tela. Com o post de hoje, eles passarão a ser listados com o endereço e um ícone identificando o tipo de restaurante que se trata.

O primeiro passo é criarmos o nosso próprio adaptador para exibir os itens na lista. Assim, na classe ListaRestaurantes, vamos criar uma classe interna, chamada AdaptadorRestaurante. Vai ficar assim:

package net.rafaeltoledo.restaurante;</p>
<p>import java.util.ArrayList;<br />
import java.util.List;</p>
<p>import net.rafaeltoledo.restaurante.model.Restaurante;<br />
import android.app.Activity;<br />
import android.os.Bundle;<br />
import android.view.View;<br />
import android.view.View.OnClickListener;<br />
import android.widget.ArrayAdapter;<br />
import android.widget.Button;<br />
import android.widget.EditText;<br />
import android.widget.ListView;<br />
import android.widget.RadioGroup;</p>
<p>public class ListaRestaurantes extends Activity {</p>
<p>	List listaRestaurantes = new ArrayList();<br />
	ArrayAdapter adaptador = null;</p>
<p>	@Override<br />
	public void onCreate(Bundle savedInstanceState) {<br />
		super.onCreate(savedInstanceState);<br />
		setContentView(R.layout.main);</p>
<p>		Button salvar = (Button) findViewById(R.id.salvar);<br />
		salvar.setOnClickListener(onSave);</p>
<p>		ListView lista = (ListView) findViewById(R.id.restaurantes);<br />
		adaptador = new ArrayAdapter(this,<br />
				android.R.layout.simple_list_item_1, listaRestaurantes);<br />
		lista.setAdapter(adaptador);<br />
	}</p>
<p>	private OnClickListener onSave = new OnClickListener() {</p>
<p>		public void onClick(View arg0) {<br />
			Restaurante r = new Restaurante();<br />
			EditText nome = (EditText) findViewById(R.id.nome);<br />
			EditText endereco = (EditText) findViewById(R.id.end);</p>
<p>			r.setNome(nome.getText().toString());<br />
			r.setEndereco(endereco.getText().toString());</p>
<p>			RadioGroup tipos = (RadioGroup) findViewById(R.id.tipos);</p>
<p>			switch (tipos.getCheckedRadioButtonId()) {<br />
			case R.id.rodizio:<br />
				r.setTipo(&quot;rodizio&quot;);<br />
				break;<br />
			case R.id.fast_food:<br />
				r.setTipo(&quot;fast_food&quot;);<br />
				break;<br />
			case R.id.a_domicilio:<br />
				r.setTipo(&quot;a_domicilio&quot;);<br />
				break;<br />
			}</p>
<p>			adaptador.add(r);<br />
		}<br />
	};</p>
<p>	class AdaptadorRestaurante extends ArrayAdapter {<br />
		AdaptadorRestaurante() {<br />
			super(ListaRestaurantes.this, android.R.layout.simple_list_item_1,<br />
					listaRestaurantes);<br />
		}<br />
	}<br />
}

O próximo passo é ajustarmos nosso layout para a nossa nova lista, já que  nessa nova listagem teremos nome, endereço e tipo (representado por uma imagem). Vamos, primeiramente, criar um layout que represente cada um dos itens da nossa listagem de forma a abrigar os três elementos. Na pasta res/layout crie o arquivo linha.xml e digite o seguinte conteúdo para ele:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br />
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;<br />
    android:layout_width=&quot;fill_parent&quot;<br />
    android:layout_height=&quot;wrap_content&quot;<br />
    android:orientation=&quot;horizontal&quot;<br />
    android:padding=&quot;4dip&quot; &gt;<br />
	&lt;ImageView android:id=&quot;@+id/icone&quot;<br />
	    android:layout_width=&quot;wrap_content&quot;<br />
	    android:layout_height=&quot;fill_parent&quot;<br />
	    android:layout_alignParentTop=&quot;true&quot;<br />
	    android:layout_alignParentBottom=&quot;true&quot;<br />
	    android:layout_marginRight=&quot;4dip&quot;/&gt;<br />
    &lt;LinearLayout<br />
        android:layout_width=&quot;fill_parent&quot;<br />
        android:layout_height=&quot;wrap_content&quot;<br />
        android:orientation=&quot;vertical&quot;&gt;<br />
        &lt;TextView android:id=&quot;@+id/titulo&quot;<br />
            android:layout_width=&quot;fill_parent&quot;<br />
            android:layout_height=&quot;wrap_content&quot;<br />
            android:layout_weight=&quot;1&quot;<br />
            android:gravity=&quot;center_vertical&quot;<br />
            android:textStyle=&quot;bold&quot;<br />
            android:singleLine=&quot;true&quot;<br />
            android:ellipsize=&quot;end&quot;/&gt;<br />
        &lt;TextView android:id=&quot;@+id/endereco&quot;<br />
            android:layout_width=&quot;fill_parent&quot;<br />
            android:layout_height=&quot;wrap_content&quot;<br />
            android:layout_weight=&quot;1&quot;<br />
            android:gravity=&quot;center_vertical&quot;<br />
            android:singleLine=&quot;true&quot;<br />
            android:ellipsize=&quot;end&quot;/&gt;<br />
    &lt;/LinearLayout&gt;<br />
&lt;/LinearLayout&gt;

Resumidamente, este layout divide cada item de listagem em duas partes (dois itens LinearLayout), sendo a primeira divisão de forma horizontal, onde à esquerda ficará a nossa imagem e, à direita, teremos outro LinearLayout, dessa vez vertical, que exibirá o nome do restaurante e o endereço.

O próximo passo é colocar as imagens em res/drawable. As imagens você pode baixar aqui. Se seu projeto tem vários diretórios chamados drawable (drawable-ldpi, por exemplo), renomeie o diretório drawable-mdpi para drawable e exclua os outros. Agora, coloque as três imagens baixadas nessa pasta.

Agora, vamos sobrescrever o método getView() na classe AdaptadorRestaurante. Este método é o responsável por exibir os itens na tela. Assim, vamos através dele utilizar o layout definido em linha.xml. Dessa forma, o arquivo ListaRestaurantes fica assim:

package net.rafaeltoledo.restaurante;</p>
<p>import java.util.ArrayList;<br />
import java.util.List;</p>
<p>import net.rafaeltoledo.restaurante.model.Restaurante;<br />
import android.app.Activity;<br />
import android.os.Bundle;<br />
import android.view.LayoutInflater;<br />
import android.view.View;<br />
import android.view.View.OnClickListener;<br />
import android.view.ViewGroup;<br />
import android.widget.ArrayAdapter;<br />
import android.widget.Button;<br />
import android.widget.EditText;<br />
import android.widget.ImageView;<br />
import android.widget.ListView;<br />
import android.widget.RadioGroup;<br />
import android.widget.TextView;</p>
<p>public class ListaRestaurantes extends Activity {</p>
<p>	List listaRestaurantes = new ArrayList();<br />
	ArrayAdapter adaptador = null;</p>
<p>	@Override<br />
	public void onCreate(Bundle savedInstanceState) {<br />
		super.onCreate(savedInstanceState);<br />
		setContentView(R.layout.main);</p>
<p>		Button salvar = (Button) findViewById(R.id.salvar);<br />
		salvar.setOnClickListener(onSave);</p>
<p>		ListView lista = (ListView) findViewById(R.id.restaurantes);<br />
		adaptador = new ArrayAdapter(this,<br />
				android.R.layout.simple_list_item_1, listaRestaurantes);<br />
		lista.setAdapter(adaptador);<br />
	}</p>
<p>	private OnClickListener onSave = new OnClickListener() {</p>
<p>		public void onClick(View arg0) {<br />
			Restaurante r = new Restaurante();<br />
			EditText nome = (EditText) findViewById(R.id.nome);<br />
			EditText endereco = (EditText) findViewById(R.id.end);</p>
<p>			r.setNome(nome.getText().toString());<br />
			r.setEndereco(endereco.getText().toString());</p>
<p>			RadioGroup tipos = (RadioGroup) findViewById(R.id.tipos);</p>
<p>			switch (tipos.getCheckedRadioButtonId()) {<br />
			case R.id.rodizio:<br />
				r.setTipo(&quot;rodizio&quot;);<br />
				break;<br />
			case R.id.fast_food:<br />
				r.setTipo(&quot;fast_food&quot;);<br />
				break;<br />
			case R.id.a_domicilio:<br />
				r.setTipo(&quot;a_domicilio&quot;);<br />
				break;<br />
			}</p>
<p>			adaptador.add(r);<br />
		}<br />
	};</p>
<p>	class AdaptadorRestaurante extends ArrayAdapter {<br />
		AdaptadorRestaurante() {<br />
			super(ListaRestaurantes.this, android.R.layout.simple_list_item_1,<br />
					listaRestaurantes);<br />
		}</p>
<p>		@Override<br />
		public View getView(int position, View convertView, ViewGroup parent) {</p>
<p>			View linha = convertView;<br />
			if (linha == null) {<br />
				LayoutInflater inflater = getLayoutInflater();<br />
				linha = inflater.inflate(R.layout.linha, null);<br />
			}</p>
<p>			Restaurante r = listaRestaurantes.get(position);</p>
<p>			((TextView) linha.findViewById(R.id.titulo)).setText(r.getNome());<br />
			((TextView) linha.findViewById(R.id.endereco)).setText(r.getEndereco());</p>
<p>			ImageView icone = (ImageView) linha.findViewById(R.id.icone);</p>
<p>			if (r.getTipo().equals(&quot;rodizio&quot;)) {<br />
				icone.setImageResource(R.drawable.rodizio);<br />
			} else if (r.getTipo().equals(&quot;fast_food&quot;)) {<br />
				icone.setImageResource(R.drawable.fast_food);<br />
			} else {<br />
				icone.setImageResource(R.drawable.entrega);<br />
			}</p>
<p>			return linha;<br />
		}<br />
	}<br />
}

Prosseguindo, precisamos agora vincular os itens da lista à nossa lista de restaurantes adicionados. Para isso, vamos criar uma classe estática que armazenará os valores para que sejam adicionados à lista exibida na tela. Adicione-a após a declaração do nosso adaptador, de forma que o nosso arquivo ListaRestaurantes.java fique assim:

package net.rafaeltoledo.restaurante;</p>
<p>import java.util.ArrayList;<br />
import java.util.List;</p>
<p>import net.rafaeltoledo.restaurante.model.Restaurante;<br />
import android.app.Activity;<br />
import android.os.Bundle;<br />
import android.view.LayoutInflater;<br />
import android.view.View;<br />
import android.view.View.OnClickListener;<br />
import android.view.ViewGroup;<br />
import android.widget.ArrayAdapter;<br />
import android.widget.Button;<br />
import android.widget.EditText;<br />
import android.widget.ImageView;<br />
import android.widget.ListView;<br />
import android.widget.RadioGroup;<br />
import android.widget.TextView;</p>
<p>public class ListaRestaurantes extends Activity {</p>
<p>	List listaRestaurantes = new ArrayList();<br />
	ArrayAdapter adaptador = null;</p>
<p>	@Override<br />
	public void onCreate(Bundle savedInstanceState) {<br />
		super.onCreate(savedInstanceState);<br />
		setContentView(R.layout.main);</p>
<p>		Button salvar = (Button) findViewById(R.id.salvar);<br />
		salvar.setOnClickListener(onSave);</p>
<p>		ListView lista = (ListView) findViewById(R.id.restaurantes);<br />
		adaptador = new ArrayAdapter(this,<br />
				android.R.layout.simple_list_item_1, listaRestaurantes);<br />
		lista.setAdapter(adaptador);<br />
	}</p>
<p>	private OnClickListener onSave = new OnClickListener() {</p>
<p>		public void onClick(View arg0) {<br />
			Restaurante r = new Restaurante();<br />
			EditText nome = (EditText) findViewById(R.id.nome);<br />
			EditText endereco = (EditText) findViewById(R.id.end);</p>
<p>			r.setNome(nome.getText().toString());<br />
			r.setEndereco(endereco.getText().toString());</p>
<p>			RadioGroup tipos = (RadioGroup) findViewById(R.id.tipos);</p>
<p>			switch (tipos.getCheckedRadioButtonId()) {<br />
			case R.id.rodizio:<br />
				r.setTipo(&quot;rodizio&quot;);<br />
				break;<br />
			case R.id.fast_food:<br />
				r.setTipo(&quot;fast_food&quot;);<br />
				break;<br />
			case R.id.a_domicilio:<br />
				r.setTipo(&quot;a_domicilio&quot;);<br />
				break;<br />
			}</p>
<p>			adaptador.add(r);<br />
		}<br />
	};</p>
<p>	class AdaptadorRestaurante extends ArrayAdapter {<br />
		AdaptadorRestaurante() {<br />
			super(ListaRestaurantes.this, android.R.layout.simple_list_item_1,<br />
					listaRestaurantes);<br />
		}</p>
<p>		@Override<br />
		public View getView(int position, View convertView, ViewGroup parent) {</p>
<p>			View linha = convertView;<br />
			if (linha == null) {<br />
				LayoutInflater inflater = getLayoutInflater();<br />
				linha = inflater.inflate(R.layout.linha, null);<br />
			}</p>
<p>			Restaurante r = listaRestaurantes.get(position);</p>
<p>			((TextView) linha.findViewById(R.id.titulo)).setText(r.getNome());<br />
			((TextView) linha.findViewById(R.id.endereco)).setText(r.getEndereco());</p>
<p>			ImageView icone = (ImageView) linha.findViewById(R.id.icone);</p>
<p>			if (r.getTipo().equals(&quot;rodizio&quot;)) {<br />
				icone.setImageResource(R.drawable.rodizio);<br />
			} else if (r.getTipo().equals(&quot;fast_food&quot;)) {<br />
				icone.setImageResource(R.drawable.fast_food);<br />
			} else {<br />
				icone.setImageResource(R.drawable.entrega);<br />
			}</p>
<p>			return linha;<br />
		}<br />
	}</p>
<p>	static class ArmazenadorRestaurante {<br />
		private TextView nome = null;<br />
		private TextView endereco = null;<br />
		private ImageView icone = null;</p>
<p>		ArmazenadorRestaurante(View linha) {<br />
			nome = (TextView) linha.findViewById(R.id.titulo);<br />
			endereco = (TextView) linha.findViewById(R.id.endereco);<br />
			icone = (ImageView) linha.findViewById(R.id.icone);<br />
		}</p>
<p>		void popularFormulario(Restaurante r) {<br />
			nome.setText(r.getNome());<br />
			endereco.setText(r.getEndereco());</p>
<p>			if (r.getTipo().equals(&quot;rodizio&quot;)) {<br />
				icone.setImageResource(R.drawable.rodizio);<br />
			} else if (r.getTipo().equals(&quot;fast_food&quot;)) {<br />
				icone.setImageResource(R.drawable.fast_food);<br />
			} else {<br />
				icone.setImageResource(R.drawable.entrega);<br />
			}<br />
		}<br />
	}<br />
}

Agora, vamos fazer o método getView utilizar a classe ArmazenadorRestaurante para montar os objetos na lista, e alteramos as referências ao ArrayAdapter para o nosso AdaptadorRestaurante, finalizando o nosso tutorial. Lembre-se de também alterar, no construtor do nosso restaurante, a referência passada para o construtor da super-classe do nosso arquivo linha.xml.

package net.rafaeltoledo.restaurante;</p>
<p>import java.util.ArrayList;<br />
import java.util.List;</p>
<p>import net.rafaeltoledo.restaurante.model.Restaurante;<br />
import android.app.Activity;<br />
import android.os.Bundle;<br />
import android.view.LayoutInflater;<br />
import android.view.View;<br />
import android.view.View.OnClickListener;<br />
import android.view.ViewGroup;<br />
import android.widget.ArrayAdapter;<br />
import android.widget.Button;<br />
import android.widget.EditText;<br />
import android.widget.ImageView;<br />
import android.widget.ListView;<br />
import android.widget.RadioGroup;<br />
import android.widget.TextView;</p>
<p>public class ListaRestaurantes extends Activity {</p>
<p>	List listaRestaurantes = new ArrayList();<br />
	AdaptadorRestaurante adaptador = null;</p>
<p>	@Override<br />
	public void onCreate(Bundle savedInstanceState) {<br />
		super.onCreate(savedInstanceState);<br />
		setContentView(R.layout.main);</p>
<p>		Button salvar = (Button) findViewById(R.id.salvar);<br />
		salvar.setOnClickListener(onSave);</p>
<p>		ListView lista = (ListView) findViewById(R.id.restaurantes);<br />
		adaptador = new AdaptadorRestaurante();<br />
		lista.setAdapter(adaptador);</p>
<p>	}</p>
<p>	private OnClickListener onSave = new OnClickListener() {</p>
<p>		public void onClick(View arg0) {<br />
			Restaurante r = new Restaurante();<br />
			EditText nome = (EditText) findViewById(R.id.nome);<br />
			EditText endereco = (EditText) findViewById(R.id.end);</p>
<p>			r.setNome(nome.getText().toString());<br />
			r.setEndereco(endereco.getText().toString());</p>
<p>			RadioGroup tipos = (RadioGroup) findViewById(R.id.tipos);</p>
<p>			switch (tipos.getCheckedRadioButtonId()) {<br />
			case R.id.rodizio:<br />
				r.setTipo(&quot;rodizio&quot;);<br />
				break;<br />
			case R.id.fast_food:<br />
				r.setTipo(&quot;fast_food&quot;);<br />
				break;<br />
			case R.id.a_domicilio:<br />
				r.setTipo(&quot;a_domicilio&quot;);<br />
				break;<br />
			}</p>
<p>			adaptador.add(r);<br />
		}<br />
	};</p>
<p>	class AdaptadorRestaurante extends ArrayAdapter {<br />
		AdaptadorRestaurante() {<br />
			super(ListaRestaurantes.this, R.layout.linha,<br />
					listaRestaurantes);<br />
		}</p>
<p>		@Override<br />
		public View getView(int position, View convertView, ViewGroup parent) {</p>
<p>			View linha = convertView;<br />
			ArmazenadorRestaurante armazenador = null;</p>
<p>			if (linha == null) {<br />
				LayoutInflater inflater = getLayoutInflater();<br />
				linha = inflater.inflate(R.layout.linha, parent, false);<br />
				armazenador = new ArmazenadorRestaurante(linha);<br />
				linha.setTag(armazenador);<br />
			} else {<br />
				armazenador = (ArmazenadorRestaurante) linha.getTag();<br />
			}</p>
<p>			armazenador.popularFormulario(listaRestaurantes.get(position));</p>
<p>			return linha;<br />
		}<br />
	}</p>
<p>	static class ArmazenadorRestaurante {<br />
		private TextView nome = null;<br />
		private TextView endereco = null;<br />
		private ImageView icone = null;</p>
<p>		ArmazenadorRestaurante(View linha) {<br />
			nome = (TextView) linha.findViewById(R.id.titulo);<br />
			endereco = (TextView) linha.findViewById(R.id.endereco);<br />
			icone = (ImageView) linha.findViewById(R.id.icone);<br />
		}</p>
<p>		void popularFormulario(Restaurante r) {<br />
			nome.setText(r.getNome());<br />
			endereco.setText(r.getEndereco());</p>
<p>			if (r.getTipo().equals(&quot;rodizio&quot;)) {<br />
				icone.setImageResource(R.drawable.rodizio);<br />
			} else if (r.getTipo().equals(&quot;fast_food&quot;)) {<br />
				icone.setImageResource(R.drawable.fast_food);<br />
			} else {<br />
				icone.setImageResource(R.drawable.entrega);<br />
			}<br />
		}<br />
	}<br />
}

Agora, se executarmos nosso aplicativo, teremos os itens adicionados à lista com seus respectivos ícones, de acordo com a categoria selecionada. O aplicativo em execução ficará assim:

Pra quem perdeu alguma parte, ou quiser baixar os resources utilizados, o projeto pode ser baixado aqui.

É isso pessoal! Espero que estejam gostando do tutorial 🙂