Página Principal

miércoles, 30 de marzo de 2016

Objetos Parcelable en Android


Si llegaron aquí, se encontraron con el problema de ¿Cómo paso objetos complejos a través de las actividades? Bueno cabe aclarar que según sé, no es la única forma (en JAVA podríamos serializar objetos). Pero, Android nativamente nos provee de esta nueva clase extendida llamada Parcelable.

No voy a comparar ni evaluar cuál es mejor, pero asumo que ésta última se integra mejor, especialmente por estar creada para Android.

Vamos a crear el típico ejemplo de objeto Persona como si fuera java pero implementando Parcelable. Se vera de esta forma:


public class Persona implements Parcelable 
{
 SimpleDateFormat formateador;
 
    String nombre;
    int edad;
    Date fechaNacimiento;
 
    public Persona() {
        super();
  formateador = new SimpleDateFormat("dd/MM/yyyy");
    }
 
    public String getNombre() {
        return nombre;
    }
 
    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
 
    public int getEdad() {
        return edad;
    }
 
    public void setEdad(int edad) {
        this.edad = edad;
    }
 
    public String getFechaNacimiento() {
        if ( fechaNacimiento!= null )
  {
   return formateador.format(fechaNacimiento);
  }
  else
  {
   return "";
  } 
    }
 
    public void setFechaNacimiento(Date fecha_Nacimiento) {
        try
  {
   this.fechaNacimiento = formateador.parse(fecha_Nacimiento);
  }
  catch (ParseException e)
  {
   this.fechaNacimiento = null;
  }
    }
 

NOTA: La fecha de nacimiento solo se guarda como Date, pero esta manejada como String y no Date. Esto es porque en Android y más precisamente si utilizamos SQLite, solo habrá TEXT. Entonces como puse en el ejemplo, será la mejor forma de capturar y formatear el objeto

Ahora bien, hasta aquí creamos un objeto común y corriente. Pero cuando implementan Parcelable les exigirá que coloquen al menos dos nuevos métodos (writeToParcel() y describeContents()). El segundo no lo utilizaras. El primero si es importante ya que nos permitirá escribir nuestro objeto en un Parcel.


@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(this.nombre);
    dest.writeInt(this.edad);
    dest.writeString(formateador.format(fechaNacimiento));
}
 

Nota: Otra ventaja de manejar la fecha como String es que tanto para escribir como leer un Parcel no reconoce la clase Date.

También es necesario crear un constructor que reciba un parámetro tipo Parcel, el cual nos permitirá crear nuestro objeto desde allí.


public Producto(Parcel in){
  super();
  formateador = new SimpleDateFormat("dd/MM/yyyy");
  readFromParcel(in);
}

private void readFromParcel(Parcel in) {

  this.nombre = in.readString();
  this.edad = in.readInt();
  try
  {
   this.fechaNacimiento = formateador.parse(in.readString());
  }
  catch (ParseException e)
  {
   this.fechaNacimiento = null;
  }    
    }

Nota Importante: Como se puede observar, tanto para leer como escribir un Parcel, no existe key o una posición o algo que nos indique que dato extraemos, por lo que en este caso el orden si altera el producto, será importante siempre escribir o leer los datos en el mismo orden o generara un error o mínimo se intercambiaran los atributos.

Ahora para generar las instancias de nuestra clase parcelable necesitamos un objeto Parcelable.Creator, el cual se verá así:


public static final Parcelable.Creator<Persona> CREATOR = new Parcelable.Creator<Persona>() {
    public Persona createFromParcel(Parcel source) {
        return new Persona(source);
    }
 
    public Persona[] newArray(int size) {
        return new Persona[size];
    }
};

Una vez hecho esto, ya tendríamos el objeto funcional. Bien ahora les mostrare como darle uso práctico en el traspaso de actividades por medio de Intent...


//En Main
 
 Persona unaPersona= new Persona();
 
 EditText nombreEdittext = (EditText) findViewById(R.id.nombreEditText);
        EditText edadEditText = (EditText) findViewById(R.id.edadEditText);
        TextView fechaTextView = (TextView) findViewById(R.id.fechaTextView);

 unaPersona.setNombre(nombreEdittext.getText().toString());
 unaPersona.setEdad(edadEditText.getText().toString());
 unaPersona.setFechaNacimiento(fechaTextView.getText().toString());
 
 Intent intent = new Intent(this, Activity2.class);     
        intent.putExtra("OBJETO_PERSONA", persona);
        startActivity(intent);
 
//En la Activity2
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity2);
 
    Bundle b = getIntent().getExtras();
    Persona persona = b.getParcelable("OBJETO_PERSONA");
 
    EditText editTextNombre = (EditText)findViewById(R.id.editTextNombre);
    EditText editTextEdad = (EditText)findViewById(R.id.editTextEdad);
    EditText editTextFecha = (EditText)findViewById(R.id.editTextFecha);
 
    editTextNombre.setText(persona.getNombre());
    editTextEdad.setText(String.valueOf(persona.getEdad()));
    editTextFecha.setText(persona.getFechaNacimiento());
 

Cualquier duda comenten
Un saludo, Cidius

1 comentario:

  1. Head Titanium Tennis racket machine for $54.00 | TITanium-arts
    Head titanium tennis titanium wedding bands for men racket machine for $54.00 · Head Titanium Tennis titanium iphone case racket machine titanium nose jewelry for $54.00 · Head Titanium Tennis titanium frames racket machine titanium piercings for $54.00 · Head TITanium Tennis racket machine for $54.00 · head

    ResponderEliminar