Tutorial Android 4 #8 – Utilizando Abas

Olá pessoal! No último post da série, adicionamos uma listagem com os contatos adicionados, mostrando um ícone indicando o tipo de contato, além do seu respectivo endereço. Hoje vamos separar a listagem do formulário, colocando uma aba para cada um.

Continuar lendo

Tutorial Android #6 – Utilizando Abas

Olá pessoal! No último post da série, adicionamos uma listagem com os restaurantes adicionados, mostrando um ícone indicando o tipo de restaurante, além do endereço. Hoje vamos separar a listagem do formulário, colocando uma aba para cada um.

O primeiro passo é modificar o nosso arquivo de layout main.xml, retirando o RelativeLayout e adicionando os itens TabHost, TabWidget e FrameLayout, que acomodarão nossos itens. Assim, o nosso novo arquivo main.xml ficará assim:

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="@+id/restaurantes"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<TableLayout
android:id="@+id/detalhes"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="1"
android:paddingTop="4dip">
<TableRow>
<TextView android:text="Nome:" />
<EditText android:id="@+id/nome" />
</TableRow>
<TableRow>
<TextView android:text="Endereço:" />
<EditText android:id="@+id/end" />
</TableRow>
<TableRow>
<TextView android:text="Tipo:" />
<RadioGroup android:id="@+id/tipos">
<RadioButton
android:id="@+id/rodizio"
android:text="Rodízio" />
<RadioButton
android:id="@+id/fast_food"
android:text="Fast Food" />
<RadioButton
android:id="@+id/a_domicilio"
android:text="A Domicílio" />
</RadioGroup>
</TableRow>
<Button
android:id="@+id/salvar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Salvar" />
</TableLayout>
</FrameLayout>
</LinearLayout>
</TabHost>
view raw main.xml hosted with ❤ by GitHub

O único detalhe que podemos salientar sobre esse novo layout, é o atributo identificador nos nós relativos às abas. @android:id/tabhost, @android:id/tabs e @android:id/tabcontent referem-se aos elementos da própria estrutura que possuem tais nomes. Por isso essa maneira “diferente” de definir este atributo (e por esse motivo não podemos alterar seus identificadores).

O próximo passo é modificar a nossa classe ListaRestaurantes para estender TabActivity, e mostrar ao TabHost como utilizar o conteúdo de nosso FrameLayout. Além disso, precisaremos de dois novos ícones, que serão exibidos para identificar cada uma das abas (lista.png e restaurante.png). Assim, primeiramente alteramos a definição da nossa classe (lembrando que pra corrigir os imports no Eclipse, é só pressionar Ctrl + Shift + O):

public class ListaRestaurantes extends TabActivity {
view raw snippet01.java hosted with ❤ by GitHub

Agora, vamos adicionar um trecho de código ao nosso método onCreate(), para que as abas funcionem corretamente. Adicione o seguinte trecho ao final do método onCreate:

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);
view raw snippet02.java hosted with ❤ by GitHub

Se executarmos nossa aplicação neste momento, ela já terá a estrutura que definimos até o momento funcionando.

Continuando, precisamos adicionar uma forma de, quando o usuário tocar sobre um dos restaurantes listados, ele possa editar suas informações no formulário. Para isso, vamos criar um listener que responda a esse evento, possibilitando manipular tal evento e realizar as tarefas necessárias. Portanto, criamos um listener OnItemClickListener em nossa classe:

private OnItemClickListener onListClick = new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
}
};
view raw snippet03.java hosted with ❤ by GitHub

Ah, e não se esqueça de adicionar este listener no método onCreate().

lista.setOnItemClickListener(onListClick);
view raw snippet04.java hosted with ❤ by GitHub

Agora, vamos fazer com que o formulário seja atualizado quando o clique (toque) for feito. Vamos criar, primeiramente, 3 atributos em nossa classe que armazenarão os valores dos campos:

EditText nome = null;
EditText endereco = null;
RadioGroup tipos = null;
view raw snippet05.java hosted with ❤ by GitHub

Em seguida, logo após a chamada ao método setContentView() no método onCreate(), adicione as seguintes linhas:

nome = (EditText) findViewById(R.id.nome);
endereco = (EditText) findViewById(R.id.end);
tipos = (RadioGroup) findViewById(R.id.tipos);
view raw snippet06.java hosted with ❤ by GitHub

Agora, vamos adicionar o corpo do método onItemClick(), para atualizar o formulário com base nos dados do item clicado.

private OnItemClickListener onListClick = new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Restaurante r = listaRestaurantes.get(position);
nome.setText(r.getNome());
endereco.setText(r.getEndereco());
if (r.getTipo().equals("rodizio")) {
tipos.check(R.id.rodizio);
} else if (r.getTipo().equals("fast_food")) {
tipos.check(R.id.fast_food);
} else {
tipos.check(R.id.a_domicilio);
}
}
};
view raw snippet07.java hosted with ❤ by GitHub

Por fim, adicionamos, também ao método onItemClick(), a chamada ao método para mudar a aba.

getTabHost().setCurrentTab(1);
view raw snippet08.java hosted with ❤ by GitHub

E pronto! Nosso exemplo está funcionando! A listagem completa da classe ListaRestaurantes é essa:

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.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView;
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.TabHost.TabSpec;
import android.widget.TextView;
public class ListaRestaurantes extends TabActivity {
List<Restaurante> listaRestaurantes = new ArrayList<Restaurante>();
AdaptadorRestaurante adaptador = null;
EditText nome = null;
EditText endereco = 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) {
Restaurante r = listaRestaurantes.get(position);
nome.setText(r.getNome());
endereco.setText(r.getEndereco());
if (r.getTipo().equals("rodizio")) {
tipos.check(R.id.rodizio);
} else if (r.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) {
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<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);
}
}
}
}

Se você perdeu alguma coisa, ou quer baixar o projeto, só clicar aqui.

Até a próxima! 🙂