Tutorial Android #5 – Aprimorando a Lista

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;

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

import net.rafaeltoledo.restaurante.model.Restaurante;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioGroup;

public class ListaRestaurantes extends Activity {

	List listaRestaurantes = new ArrayList();
	ArrayAdapter adaptador = null;

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

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

		ListView lista = (ListView) findViewById(R.id.restaurantes);
		adaptador = new ArrayAdapter(this,
				android.R.layout.simple_list_item_1, listaRestaurantes);
		lista.setAdapter(adaptador);
	}

	private OnClickListener onSave = new OnClickListener() {

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

			r.setNome(nome.getText().toString());
			r.setEndereco(endereco.getText().toString());

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

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

			adaptador.add(r);
		}
	};

	class AdaptadorRestaurante extends ArrayAdapter {
		AdaptadorRestaurante() {
			super(ListaRestaurantes.this, android.R.layout.simple_list_item_1,
					listaRestaurantes);
		}
	}
}

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:

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

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;

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

import net.rafaeltoledo.restaurante.model.Restaurante;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
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.TextView;

public class ListaRestaurantes extends Activity {

	List listaRestaurantes = new ArrayList();
	ArrayAdapter adaptador = null;

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

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

		ListView lista = (ListView) findViewById(R.id.restaurantes);
		adaptador = new ArrayAdapter(this,
				android.R.layout.simple_list_item_1, listaRestaurantes);
		lista.setAdapter(adaptador);
	}

	private OnClickListener onSave = new OnClickListener() {

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

			r.setNome(nome.getText().toString());
			r.setEndereco(endereco.getText().toString());

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

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

			adaptador.add(r);
		}
	};

	class AdaptadorRestaurante extends ArrayAdapter {
		AdaptadorRestaurante() {
			super(ListaRestaurantes.this, android.R.layout.simple_list_item_1,
					listaRestaurantes);
		}

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

			View linha = convertView;
			if (linha == null) {
				LayoutInflater inflater = getLayoutInflater();
				linha = inflater.inflate(R.layout.linha, null);
			}

			Restaurante r = listaRestaurantes.get(position);

			((TextView) linha.findViewById(R.id.titulo)).setText(r.getNome());
			((TextView) linha.findViewById(R.id.endereco)).setText(r.getEndereco());

			ImageView icone = (ImageView) linha.findViewById(R.id.icone);

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

			return linha;
		}
	}
}

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;

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

import net.rafaeltoledo.restaurante.model.Restaurante;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
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.TextView;

public class ListaRestaurantes extends Activity {

	List listaRestaurantes = new ArrayList();
	ArrayAdapter adaptador = null;

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

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

		ListView lista = (ListView) findViewById(R.id.restaurantes);
		adaptador = new ArrayAdapter(this,
				android.R.layout.simple_list_item_1, listaRestaurantes);
		lista.setAdapter(adaptador);
	}

	private OnClickListener onSave = new OnClickListener() {

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

			r.setNome(nome.getText().toString());
			r.setEndereco(endereco.getText().toString());

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

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

			adaptador.add(r);
		}
	};

	class AdaptadorRestaurante extends ArrayAdapter {
		AdaptadorRestaurante() {
			super(ListaRestaurantes.this, android.R.layout.simple_list_item_1,
					listaRestaurantes);
		}

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

			View linha = convertView;
			if (linha == null) {
				LayoutInflater inflater = getLayoutInflater();
				linha = inflater.inflate(R.layout.linha, null);
			}

			Restaurante r = listaRestaurantes.get(position);

			((TextView) linha.findViewById(R.id.titulo)).setText(r.getNome());
			((TextView) linha.findViewById(R.id.endereco)).setText(r.getEndereco());

			ImageView icone = (ImageView) linha.findViewById(R.id.icone);

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

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

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;

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

import net.rafaeltoledo.restaurante.model.Restaurante;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
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.TextView;

public class ListaRestaurantes extends Activity {

	List listaRestaurantes = new ArrayList();
	AdaptadorRestaurante adaptador = null;

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

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

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

	}

	private OnClickListener onSave = new OnClickListener() {

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

			r.setNome(nome.getText().toString());
			r.setEndereco(endereco.getText().toString());

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

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

			adaptador.add(r);
		}
	};

	class AdaptadorRestaurante extends ArrayAdapter {
		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);
			}
		}
	}
}

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 🙂

8 comentários sobre “Tutorial Android #5 – Aprimorando a Lista

  1. André Kunde disse:

    Muito bom esse seu tutorial, Parabens!!

    Estou acompanhando ele e tive um pouco de dificuldades nesta parte (#5).
    Depois de ter conferido 2 vezes o projeto todo, resolvi baixar o projeto completo para conferir e notei que o arquivo ListaRestaurantes.java esta um pouco diferente.

    Curtir

    • Opa, valeu André! Realmente, me lembrando agora, teve um post onde eu fiz o exemplo passo a passo e no final ele não rodou. Aí eu garimpei o código atrás de erro e acho que esqueci de atualizar no tutorial. A hora que tiver um tempinho eu faço uma revisão nele.

      De qualquer forma, continue acompanhando e obrigado pela visita! 🙂

      Curtir

  2. Lucas disse:

    Boa tarde Rafael estou com um problema envolvendo listas no android, preciso colocar um edittext como componente da linha mas, ao editar o conteudo de qualquer um da dos que aparece na tela todos os demais assumem o mesmo valor e, ao rolar a lista para exibir as demais linhas os campos voltam ao valor inicial.
    Como faço para resolver esse problema?
    Grato pela ajuda,

    Lucas P. Rosseti

    Curtir

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.