segunda-feira, 11 de março de 2013

Android - Trabalhando com parametrização de telas


Em diversas situações temos a necessidade de transportar informações de uma tela para outra, como por exemplo: em uma tela de venda quando adicionamos um produto, uma tela de pesquisa ou até mesmo quando usamos uma tela padrão para realizar várias tarefas. O uso de parâmetros se torna imprescindível quando estamos desenvolvendo praticamente qualquer tipo de software. No Sistema Android também faremos o uso deste procedimento, utilizando recursos próprios para isto. O método mais comum seria de Atividade (“Activity”) para Atividade (“Activity”) usando as classes “android.content.Intent”, a “android.os.bundle” e a “android.app.Activity”. É importante salientar a possibilidade de passar parâmetros desde um tipo numérico ou texto até um Objeto de uma classe inteira.

Conhecendo as Classes

1-) android.app.Activity: Esta classe é uma das mais importantes do Sistema Android, sendo que possuímos um artigo publicado no mês de Setembro de 2012, com o título “Android – Ciclo de vida de uma Atividade” a descrevendo de uma forma mais completa. O que interessa neste caso são os métodos “startActivityForResult()” servindo para obter um resultado de volta a partir de uma Atividade quando é finalizada e o “getIntent()” para retornar o “Intent” que será recebido.

startActivityForResult(Intent intent, int requestCode) : Identifica a “Intent” e a chamada respectivamente. O resultado será retornado através de seu método “OnActivityResult()”. O método “SetResult()” é utilizado quando finalizamos uma atividade, fornecendo os dados e um código de controle para a Atividade principal.

getIntent(): Apenas retorna o “Intent”.


2-) android.content.Intent:
 Seu uso mais significativo é  no lançamento de Atividades, é uma estrutura que permite tanto a passagem quanto o recebimento de parâmetros. Os principais métodos são: o “putExtra()”, possuindo diversas implementações. Recebe como parâmetros o denominado par chave/valor, sendo o primeiro parâmetro uma String com o nome e o seguinte o tipo de dados em questão e o “getExtras()” servindo para recuperar todos os dados anteriormente adicionados com o “putExtra()”.

putExtra(String name, int value) : Valor do tipo Inteiro.
putExtra(String name, String value) :  Valor do tipo Texto.
putExtra(String name, Bundle value) : Valor do tipo Bundle.
putExtra(String name, double[] value) : Valor do tipo Array de numérico real.
putExtra(String name, float value) : Valor do tipo numerico real.
getExtras() : Apenas retorna os dados adicionados.

3 ) android.os.Bundle:
A classe “Bundle” funciona como uma tabela de registros, cada um com valores chaves associadas, servindo para passar conteúdos extras ao chamar outra Atividade, para dizer o que fazer quando a mesma for criada.

Criando um exemplo

Depois de conhecermos um pouco das principais classes, montaremos um pequeno exemplo para maior aprendizado. Este exemplo possuirá duas telas responsáveis por enviar e receber diversos tipos de parâmetros. Para isto abra seu Eclipse e clique em “File/New/Android Project” e crie um projeto em Android, recomendo a criação na versão 2.2 ou 2.3 utilizando o nome que desejar. No meu caso criei como “Android_Parametros”.
Utilizaremos dois arquivos de lay-outs (“principal.xml” e “secundaria.xml”) seguindo duas Atividades (“principalAtividade.java” e “secundariaAtividade.java”). O primeiro passo é atribuir no arquivo de configuração “AndroidManifest.xml” as suas devidas Atividades. Veja abaixo o XML.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="pct.Android_Parametros"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="8" />
    <application android:icon="@drawable/icon"
    android:label="The Club - Parametrização de Telas">
       
        <activity android:name="principalAtividade"
        android:label="The Club - Tela Principal">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
       
        <activity android:name="secundariaAtividade"
        android:label="The Club - Tela Secundária">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>
       
    </application>
</manifest>

Arquivos de “Lay-Out”

1) Principal.xml

A tela principal deverá possuir componentes referentes aos parâmetros que enviaremos e aos que receberemos. Para isto 
adicione 9 TextViews, 3 EditTexts e um Button.

Ver Imagem 01.

Figura 01: Tela Principal.

O XML correspondente:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+principal/LinearLayout1"
    >
    <TextView
    android:id="@+principal/lbParametros"
    android:layout_width="fill_parent"
    android:text="Parâmetros de Entrada"
    android:layout_height="50dp"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:typeface="sans"
    android:textColor="#FFFFFF"
    android:textStyle="bold"
    android:gravity="center">
    </TextView>
    <TextView android:layout_width="wrap_content"
    android:text="Código:"
    android:id="@+principal/lbCodigo"
    android:layout_height="wrap_content"
    android:gravity="right"
    android:typeface="sans"
    android:textColor="#FFFFFF"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:textStyle="bold"
    android:layout_gravity="left|right">
    </TextView>
    <EditText android:layout_height="wrap_content"
    android:inputType="numberDecimal"
    android:typeface="sans"
    android:id="@+principal/edtCodigo"
    android:layout_gravity="left|right"
    android:layout_width="92dp">
    </EditText>
    <TextView android:layout_width="wrap_content"
    android:text="Produto:"
    android:id="@+principal/lbProduto"
    android:layout_height="wrap_content"
    android:gravity="right"
    android:typeface="sans"
    android:textColor="#FFFFFF"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:textStyle="bold"
    android:layout_gravity="left|right">
    </TextView>
    <EditText android:layout_height="wrap_content"
    android:inputType="text"
    android:typeface="sans"
    android:id="@+principal/edtProduto"
    android:layout_gravity="left|right"
    android:layout_width="match_parent">
    </EditText>
    <TextView android:layout_width="wrap_content"
    android:text="Tipo:"
    android:id="@+principal/lbTipo"
    android:layout_height="wrap_content"
    android:gravity="right"
    android:typeface="sans"
    android:textColor="#FFFFFF"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:textStyle="bold"
    android:layout_gravity="left|right">
    </TextView>
    <EditText android:layout_height="wrap_content"
    android:inputType="text"
    android:typeface="sans"
    android:id="@+principal/edtTipo"
    android:layout_gravity="left|right" android:layout_width="194dp">
    </EditText>
    <Button android:layout_height="wrap_content"
    android:text="Tela Secundária"
    android:id="@+principal/btnSecundaria"
    android:layout_width="150dp"
    android:gravity="center"
    android:layout_gravity="center">
    </Button>
    <TextView android:layout_width="fill_parent"
    android:text="Parâmetros de Retorno"
    android:layout_height="50dp"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:typeface="sans"
    android:textColor="#FFFFFF"
    android:textStyle="bold"
    android:gravity="center">
    </TextView>
    <TextView android:layout_width="wrap_content"
    android:text="Quantidade:"
    android:id="@+principal/lbQuan"
    android:layout_height="wrap_content"
    android:gravity="right"
    android:typeface="sans"
    android:textColor="#FFFFFF"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:textStyle="bold"
    android:layout_gravity="left|right">
    </TextView>
    <TextView android:layout_width="wrap_content"
    android:text="0,00"
    android:id="@+principal/lbQuantidade"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textColor="#FFFFFF"
    android:textStyle="bold" >
    </TextView>
    <TextView android:layout_width="wrap_content"
    android:text="Valor:"
    android:id="@+principal/lbVal"
    android:layout_height="wrap_content"
    android:gravity="right"
    android:typeface="sans"
    android:textColor="#FFFFFF"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:textStyle="bold"
    android:layout_gravity="left|right">
    </TextView>
    <TextView android:layout_width="wrap_content"
    android:text="R$ 0,00"
    android:id="@+principal/lbValor"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:textColor="#FFFFFF"
    android:textStyle="bold">
    </TextView>
</LinearLayout>
Nesta tela é onde inserimos os dados (Código, Produto e Tipo) e os passamos por parâmetro para a tela seguinte. Os campos (Quantidade e Valor) receberão o retorno da tela secundária.

2-) Secundaria.xml

A tela secundária deverá possuir os seguintes componentes: 10 TextViews, 2 EditTexts e um Button. Ver Imagem 02.

Figura 02: Tela Secundária.

O XML correspondente:

<?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="fill_parent"
    android:orientation="vertical"
    android:weightSum="1">
    <LinearLayout android:id="@+secundaria/linearLayout1"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:weightSum="1"
    android:layout_height="450dp">
        <TextView android:text="Parâmetros de Entrada"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:gravity="center"
        android:textColor="#FFFFFF"
        android:layout_height="50dp"
        android:typeface="sans"
        android:layout_width="fill_parent"
        android:id="@+secundaria/lbParametros"
        android:textStyle="bold">
        </TextView>
        <TextView android:layout_width="wrap_content"
        android:text="Código:"
        android:id="@+secundaria/lbCod"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:typeface="sans"
        android:textColor="#FFFFFF"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_gravity="left|right"
        android:textStyle="bold">
        </TextView>
        <TextView android:text="TextView"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:id="@+secundaria/lbCodigo">
        </TextView>
        <TextView android:layout_width="wrap_content"
        android:text="Produto:"
        android:id="@+secundaria/lbProd"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:typeface="sans"
        android:textColor="#FFFFFF"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_gravity="left|right"
        android:textStyle="bold">
        </TextView>
        <TextView android:text="TextView"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:id="@+secundaria/lbProduto">
        </TextView>
        <TextView android:layout_width="wrap_content"
        android:text="Tipo:"
        android:id="@+secundaria/lbTip"
        android:layout_height="wrap_content"
        android:gravity="right"
        android:typeface="sans"
        android:textColor="#FFFFFF"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_gravity="left|right"
        android:textStyle="bold">
        </TextView>
        <TextView android:text="TextView"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:id="@+secundaria/lbTipo">
        </TextView>
        <TextView android:text="Parâmetros de Retorno"
        android:id="@+secundaria/lbRetorno"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:gravity="center"
        android:textColor="#FFFFFF"
        android:layout_height="50dp"
        android:typeface="sans"
        android:layout_width="fill_parent"
        android:textStyle="bold">
        </TextView>
        <TextView android:text="Quantidade:"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="#FFFFFF"
        android:layout_height="wrap_content"
        android:typeface="sans"
        android:layout_width="wrap_content"
        android:id="@+secundaria/lbQuantidade"
        android:textStyle="bold"
        android:layout_gravity="left|right"
        android:gravity="left|right">
        </TextView>
        <EditText android:layout_height="wrap_content"
        android:typeface="sans"
        android:inputType="numberDecimal"
        android:id="@+secundaria/edtQuantidade"
        android:layout_width="114dp"
        android:layout_gravity="left|right"
        android:gravity="left|right">
        </EditText>
        <TextView android:text="Valor Unit.:"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="#FFFFFF"
        android:layout_height="wrap_content"
        android:typeface="sans"
        android:layout_width="wrap_content"
        android:id="@+secundaria/lbValor_Unitario"
        android:textStyle="bold"
        android:layout_gravity="left|right"
        android:gravity="left|right">
        </TextView>
        <EditText android:layout_height="wrap_content"
        android:typeface="sans"
        android:inputType="numberDecimal"
        android:id="@+secundaria/edtValor_Unitario"
        android:layout_width="112dp"
        android:layout_gravity="left|right"
        android:gravity="left|right">
        </EditText>
        <Button android:text="Tela Principal"
        android:id="@+secundaria/btnPrimaria"
        android:layout_height="wrap_content"
        android:typeface="sans"
        android:layout_gravity="center"
        android:layout_width="216dp">
        </Button>
    </LinearLayout>
</LinearLayout>

Nesta tela recebemos os parâmetros (Código, Produto, Tipo) e enviamos os campos (Quantidade e Valor).

Codificando o Exemplo

1-) principalAtividade.java

O primeiro passo seria importar algumas bibliotecas necessárias, veja a seguir:

package pct.Android_Parametros;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class principalAtividade extends Activity
{
      EditText edtCodigo, edtProduto, edtTipo;
      TextView lbQuantidade, lbValor;
      Button btnSecundaria;

Estas variáveis são necessárias para inicializar os componentes contidos na tela.
     
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.principal);
        InicializaListeners();
       
        btnSecundaria.setOnClickListener(new View.OnClickListener() {
           
      @Override
      public void onClick(View arg0)
      {
            Integer codigo = Integer.parseInt(edtCodigo.getText().toString());
            String produto = edtProduto.getText().toString();
            String tipo = edtTipo.getText().toString();
           
            Intent Isecundaria = new Intent(principalAtividade.this, secundariaAtividade.class);
            Isecundaria.putExtra("codigo", codigo);
            Isecundaria.putExtra("produto", produto);
            Isecundaria.putExtra("tipo", tipo);
            startActivityForResult(Isecundaria,1);
      }
      });

    }

O evento “OnClick” do botão é o local onde passamos os parâmetros “Código”, “Produto” e “Tipo”. Primeiramente é criado um objeto do tipo “Intent” e em seguida utilizaremos o método “putExtra()”, sendo responsável por armazenar os parâmetros. O método “startActivityForResult()” irá chamar a tela secundária e retornar os parâmetros nela contidos.
   
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
      if (requestCode == 1 && data != null)
      {
            lbQuantidade.setText(data.getExtras().getString("quantidade"));
            lbValor.setText(data.getExtras().getString("valor"));
        }
    }   

Este é o método responsável por tratar dos valores adquiridos anteriormente. O comando “getExtras()” permite a leitura dos dados.
   
    public void InicializaListeners()
    {
      edtCodigo = (EditText) findViewById(R.principal.edtCodigo);
      edtProduto = (EditText) findViewById(R.principal.edtProduto);
      edtTipo = (EditText) findViewById(R.principal.edtTipo);
      lbQuantidade = (TextView) findViewById(R.principal.lbQuantidade);
      lbValor = (TextView) findViewById(R.principal.lbValor);
      btnSecundaria = (Button) findViewById(R.principal.btnSecundaria);
    }
}
Procedimento necessário para iniciar as variáveis pelo “Id” do objeto.
2-) secundariaAtividade.java
Seguiremos os mesmos passos descritos anteriormente, importando algumas bibliotecas necessárias para o funcionamento.
package pct.Android_Parametros;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class secundariaAtividade extends Activity
{
      TextView lbCodigo, lbProduto, lbTipo;
      EditText edtQuantidade, edtValor;
      Button btnPrimaria;

Variáveis utilizadas para inicializar os objetos através do método “InicializaListeners”.

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.secundaria);
        InicializaListeners();
       
        Intent Idadosrecebidos = getIntent();
        if (Idadosrecebidos != null)
        {
            Bundle parametrosRecebidos = Idadosrecebidos.getExtras();
            if (parametrosRecebidos != null)
            {
                              lbCodigo.setText(String.valueOf(parametrosRecebidos.getInt("codigo")));
                  lbProduto.setText(parametrosRecebidos.getString("produto"));
                  lbTipo.setText(parametrosRecebidos.getString("tipo"));
            }
        }
       
No evento “Oncreate()” da Atividade iremos carregar os dados que foram enviados por parâmetros, para isto foi criado um Objeto do tipo “Intent” para armazená-los e recuperá-los posteriormente. O Objeto do tipo “Bundle” nos permite a extração dos campos “Código”, “Produto” e “Tipo”.
       

btnPrimaria.setOnClickListener(new View.OnClickListener()
        {
            @Override
           public void onClick(View arg0)
           {    
                Intent data = new Intent();
                  data.putExtra("quantidade", edtQuantidade.getText().toString());
                data.putExtra("valor", edtValor.getText().toString());
                  setResult(1, data);
                  finish();
           }
        });
    }
   
Já no evento “Onclick” do botão iremos transportar os campos “Quantidade” e “Valor” para a Atividade Principal usando o método “putExtra()” seguido do “SetResult()”, o mesmo que trabalha em sintonia com o método “startActivityForResult()” citado anteriormente. Para fechar a Atividade invoque o método “Finish()”

    public void InicializaListeners()
    {
      lbCodigo = (TextView) findViewById(R.secundaria.lbCodigo);
      lbProduto = (TextView) findViewById(R.secundaria.lbProduto);
      lbTipo = (TextView) findViewById(R.secundaria.lbTipo);
      edtQuantidade = (EditText) findViewById(R.secundaria.edtQuantidade);
      edtValor = (EditText) findViewById(R.secundaria.edtValor_Unitario);
      btnPrimaria = (Button) findViewById(R.secundaria.btnPrimaria);
    }
}
Compile e rode a aplicação, teremos um resultado parecido com as Imagens 03, 04 e 05.

Figura 03: Inserindo Parâmetros

Figura 04: Recebendo e enviando parâmetros.

Figura 05: Resultado Final.
Conclusão

O recurso de parametrização de telas é muito utilizado no dia-a-dia no desenvolvimento de aplicações. O Sistema Android possui diversas classes responsáveis por este trabalho e minha intenção neste artigo foi de demonstrar de uma maneira prática o uso destes recursos. De primeiro momento descrevi algumas características das classes “android.app.Activity”, “android.content.Intent” e “android.os.Bundlee logo após seguindo um exemplo prático englobando estes recursos.
Fico por aqui, um forte abraço e um ótimo início de Ano!

Referências