quarta-feira, 26 de janeiro de 2011

Como transferir objetos entre layouts.

Olá amigos.

Neste post veremos como é possível passar um valor de uma página (layout) para outra página em uma aplicação Android.
Existe uma pequena diferença entre passar um objeto do tipo primitivo e um objeto composto.
Abordaremos ambas as soluções a seguir.

A funcionalidade é bem parecida com uma implementação de Map, do Java, onde você cria um objeto e nele você seta um objeto e sua respectiva chave e o recupera posteriormente.

Para passar um simples objeto.

Para "chamar" uma nova página, criamos um objeto do tipo Intent, como já vimos no blog.
Para passarmos algum valor/objeto entre telas, precisamos adicionar "extras" no nosso objeto, da forma descrita abaixo:

// Cria a chamada para a página Page2
Intent myIntent = new Intent(v.getContext(), Page2.class);

// seta um valor extra, utilizando uma chave e um valor.
myIntent.putExtra("chaveTeste", "Novo Objeto");

// Inicia a nova página.
startActivity(myIntent);

Chamamos o método putExtra(chave,valor) passando uma "chave" que é um identificador para você poder recuperar o valor passado em outra tela e também pare diferenciar caso você passe outros valores no mesmo Intent. E também passasse como segundo paramêtro um valor, que pode ser um objeto do tipo primitivo ou composto.
Para ver a lista de objetos aceitos pelo método, favor checar na API do Android : http://developer.android.com/reference/android/content/Intent.htm

Agora, na outra tela, precisamos resgatar este valor, portanto fazemos da seguinte maneira:

Bundle extras = getIntent().getExtras();
String novoTexto = (String) extras.get("chaveTeste");

Simples não? Só precisamos chamar o método getIntent() e o getExtras() dele que teremos um objeto do tipo Bundle, que contém os valores passados neste Intent. Depois disso, basta usarmos o método .get() passando a chave utilizada que recuperamos o objeto. Você precisará fazer um Cast para o seu tipo, pois o método extras.get() retorna um Object.

Para passar um objeto criado por você.

Para essa situação, seu objeto deve implementar a interface Parcelable, como fiz no exemplo abaixo:

package com.navegandoentrelayouts;

import android.os.Parcel;
import android.os.Parcelable;

public class Usuario implements Parcelable {

    // Propriedades
    private long registro;
    private String nome;

    // Construtores
    public Usuario() {
    }

    public Usuario(long registro, String nome) {
        super();
        this.registro = registro;
        this.nome = nome;
    }

    public Usuario(Parcel in) {
        readFromParcel(in);
    }

    // Getters e setters
    public long getRegistro() {
        return registro;
    }

    public String getNome() {
        return nome;
    }

    public void setRegistro(long registro) {
        this.registro = registro;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    // Método auxilirares
    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeLong(registro);
        out.writeString(nome);
    }

    private void readFromParcel(Parcel in) {

        registro = in.readLong();
        nome = in.readString();
    }

    @SuppressWarnings("unchecked")
    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public Usuario createFromParcel(Parcel in) {
            return new Usuario(in);
        }

        public Usuario[] newArray(int size) {
            return new Usuario[size];
        }
    };
}

O próximo passo é setar o objeto no Intent:

// Cria a chamada para a página Page2
Intent myIntent = new Intent(v.getContext(), Page2.class);

// Crio o meu objeto.
Usuario usuario = new Usuario(15L, "Rafael");

// seta um valor extra, utilizando uma chave e um valor.
myIntent.putExtra("usuario", usuario);

// Inicia a nova página.
startActivity(myIntent);

Para recuperar o objeto enviado utilizaremos uma outra forma. E é por esta razão que implementamos a interface Parcelable.
Desta vez, você não irá chamar o método .get() para recuperar o Bundle, e sim o método getParcelable(), onde você passa a mesma chave que passou para setar o objeto no Intent.

Veja o exemplo:

// Passa a chave, faz um Cast e tenha o objeto
Usuario usuario = (Usuario) extras.getParcelable("usuario");

Pronto. Agora você já tem o objeto recuperado na outra tela e pode trafegar informações entre elas.


7 comentários:

  1. Olá, poderia me explicar como funciona da linha 61 em diante???

    ResponderExcluir
  2. Olá, Odete.
    temos que implementar essa interface para conseguirmos recuperar o objeto na outra página.
    Para mais informações, você pode dar uma olhada na API.
    http://developer.android.com/reference/android/os/Parcelable.Creator.html
    Abraços

    ResponderExcluir
  3. ajudou muito agora, msm sendo um post antigo.

    ResponderExcluir
  4. Como faço pra passar uma lista dessa classe para outra tela?

    ResponderExcluir
    Respostas
    1. Insira o GSON em seu buid.gradle
      compile 'com.google.code.gson:gson:2.2.4'

      E passa a lista desta maneira:

      final String toJson = new Gson().toJson(SUA_LISTA_AQUI);
      final Intent intent = new Intent(getActivity(), ProximaActivity.class);
      intent.putExtra("key", toJson);
      startActivity(intent);

      E na ProximaActivity, para recuperar o valor, faça desta maneira:

      String value = getIntent().getExtras().getString("key");
      Type listType = new TypeToken>() {
      }.getType();
      List list = new Gson().fromJson(value, listType);

      Duvidas é só falar.
      Abraços

      Excluir