Tutorial Android 4 #8 – Utilizando Abas

Padrão

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.

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

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <ListView
                android:id="@+id/contatos"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

            <RelativeLayout
                android:id="@+id/detalhes"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" >

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_alignParentTop="true"
                    android:orientation="vertical" >

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/nome" />

                    <EditText
                        android:id="@+id/nome"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:inputType="text" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/email" />

                    <EditText
                        android:id="@+id/email"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:inputType="textEmailAddress" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@string/tipo_contato" />

                    <RadioGroup
                        android:id="@+id/tipo_contato"
                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content" >

                        <RadioButton
                            android:id="@+id/pessoal"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@string/tipo_pessoal" />

                        <RadioButton
                            android:id="@+id/profissional"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@string/tipo_profissional" />

                        <RadioButton
                            android:id="@+id/academico"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="@string/tipo_academico" />
                    </RadioGroup>
                </LinearLayout>

                <Button
                    android:id="@+id/salvar"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:text="@string/salvar" />
            </RelativeLayout>
        </FrameLayout>
    </LinearLayout>

</TabHost>

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 chaves do layout de abas, que possuem tais nomes internamente no Android. Assim, precisamos colocar esses ids para que o layout seja montado corretamente (e por esse motivo não podemos alterar seus identificadores).

O próximo passo é modificar o nosso o método onCreate da classe MeusContatos para carregar o layout de abas e dividir o conteúdo entre elas. Carregamos o nosso TabHost e, a partir dele, criamos as outras abas programaticamente. Adicione o seguinte código logo após a chamada ao setContentView().

TabHost abas = (TabHost) findViewById(R.id.tabhost);
abas.setup();

TabSpec descritor = abas.newTabSpec("aba1");
descritor.setContent(R.id.contatos);
descritor.setIndicator(getString(R.string.contatos));
abas.addTab(descritor);

descritor = abas.newTabSpec("aba2");
descritor.setContent(R.id.detalhes);
descritor.setIndicator(getString(R.string.detalhes));
abas.addTab(descritor);

Criamos, então, duas abas, uma com o título de Contatos e a outra com o título de Detalhes. Ah, lembrem-se de criar as duas strings lá no nosso arquivo strings.xml! Isso para, posteriormente, podermos facilmente internacionalizar nosso aplicativo 🙂

Se executarmos neste momento nosso aplicativo, ele já terá o visual que desejamos:

tutorial-android-01tutorial-android-02

Continuando, precisamos adicionar uma forma de que, quando o usuário tocar sobre um dos contatos da lista, ele possa editar suas informações no formulário. Para isso, vamos criar fazer a nossa classe implementar mais um listener, o OnItemClickListener, para que tenhamos um feedback para esse evento, possibilitando manipulá-lo e realizar as tarefas necessárias. Portanto, vamos fazer a nossa classe implementar tal listener e vamos implementar o método que a interface exige.

public class MeusContatos extends Activity implements OnClickListener, OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}

Agora, vamos adicionar a nossa classe como listener da lista.

lista.setOnItemClickListener(this);

Por organização, vamos fazer uma separação dos elementos de interface, colocando-os como atributos da nossa classe. Isso nos ajudará a deixá-la mais organizada e facilitará a implementação da funcionalidade de editar um registro ao clicar em um item da lista. Dessa forma, vamos adicionar os quatro elementos assim:

private List<Contato> contatos = new ArrayList<Contato>();
private ContatoAdapter adaptador = null;

private TabHost abas = null;
private EditText nome = null;
private EditText email = null;
private RadioGroup tipoContato = null;
private Button salvar = null;

Em seguida, vamos editar o método onCreate() para que inicialize estas variáveis para nós.

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_meus_contatos);

	abas = (TabHost) findViewById(R.id.tabhost);
	abas.setup();

	TabSpec descritor = abas.newTabSpec("aba1");
	descritor.setContent(R.id.contatos);
	descritor.setIndicator(getString(R.string.contatos));
	abas.addTab(descritor);

	descritor = abas.newTabSpec("aba2");
	descritor.setContent(R.id.detalhes);
	descritor.setIndicator(getString(R.string.detalhes));
	abas.addTab(descritor);

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

	nome = (EditText) findViewById(R.id.nome);
	email = (EditText) findViewById(R.id.email);

	tipoContato = (RadioGroup) findViewById(R.id.tipo_contato);

	ListView lista = (ListView) findViewById(R.id.contatos);
	adaptador = new ContatoAdapter();
	lista.setAdapter(adaptador);
	lista.setOnItemClickListener(this);
}

Como transferimos a inicialização dos componentes para o método onCreate(), podemos retirá-la do método onClick(), deixando-o mais leve:

@Override
public void onClick(View v) {
	Contato contato = new Contato();
	contato.setNome(nome.getText().toString());
	contato.setEmail(email.getText().toString());

	switch (tipoContato.getCheckedRadioButtonId()) {
	case R.id.pessoal:
		contato.setTipo(Contato.Tipo.PESSOAL);
		break;
	case R.id.profissional:
		contato.setTipo(Contato.Tipo.PROFISSIONAL);
		break;
	case R.id.academico:
		contato.setTipo(Contato.Tipo.ACADEMICO);
		break;
	}

	adaptador.add(contato);
}

Vamos, então adicionar a implementação do método onItemClick(), para atualizar o formulário com base nos dados do item clicado.

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
	Contato c = contatos.get(position);
	nome.setText(c.getNome());
	email.setText(c.getEmail());

	switch (c.getTipo()) {
	case ACADEMICO:
		tipoContato.check(R.id.academico);
		break;
	case PESSOAL:
		tipoContato.check(R.id.pessoal);
		break;
	case PROFISSIONAL:
		tipoContato.check(R.id.profissional);
		break;
	}

	abas.setCurrentTab(1);
}

Neste método simplesmente obtemos o objeto do tipo Contato que foi clicado e injetamos seus dados nos elementos da tela, mudando para a aba do formulário logo em seguida.

Por fim, vamos fazer um pequeno ajuste no método onClick(), para que ele limpe o formulário e mude para a listagem ao se salvar o contato. Para auxiliar, vamos criar um método limparFormulario() para facilitar o entendimento do código:

@Override
public void onClick(View v) {
	Contato contato = new Contato();
	contato.setNome(nome.getText().toString());
	contato.setEmail(email.getText().toString());

	switch (tipoContato.getCheckedRadioButtonId()) {
	case R.id.pessoal:
		contato.setTipo(Contato.Tipo.PESSOAL);
		break;
	case R.id.profissional:
		contato.setTipo(Contato.Tipo.PROFISSIONAL);
		break;
	case R.id.academico:
		contato.setTipo(Contato.Tipo.ACADEMICO);
		break;
	}

	adaptador.add(contato);

	abas.setCurrentTab(0);
	limparFormulario();
}

private void limparFormulario() {
	nome.setText("");
	email.setText("");
	tipoContato.check(0);
}

E é isso! Nosso sistema tem um pequeno bug de duplicar o contato ao editá-lo, mas fiquem tranquilos pois vamos corrigi-lo logo logo! 🙂

Pra quem precisar, pode baixar o código do projeto aqui. Até a próxima!

4 comentários sobre “Tutorial Android 4 #8 – Utilizando Abas

  1. Leonardo Frangelli

    Dae brother.. Muito legal seus tutoriais. Não vai rolar agora a parte de salvar isso no sqlite? Fiz um outro aqui e estou querendo ver sua forma de fazer.

    Vlw.

  2. Gabriel

    Cara, muito bom mesmo esse tutorial!
    Tá me ajudando bastante agora que to mexendo com Android.
    Não tem como voce começar a mostrar a parte de Banco de Dados??
    To na torcida aqui por isso hein!!
    Tá de Parabens!!

  3. Matheus Weber

    Boa noite, primeiramente quero agradecer pela série de tutoriais sobre Android que você postou em seu blog, eu precisava criar um sistema para gravar textos criptografados, e graças a seu tutorial consegui fazer isso. Porém agora eu preciso de uma ajuda bem simples, preciso saber como fazer para exibir um “contato” da sua agenda na integra, porque preciso finalizar esse trabalho, preciso fazer com que o usuário escolha um metodo desemcriptografamento e tente-o usar no texto, no caso seria a mera exibição do seu contato, tem como me ajudar nisso? Desculpa se estou sendo muito invasivo, mas se você pudesse indicar algum tutorial, pois não acho mais nada.

Deixe uma resposta