online - Clase de Android parcelable con ArrayList
parcelable creator (4)
Tengo un proyecto de Android donde tengo una clase. En esa clase hay un ArrayList<Choices>
. Obtendré algo de XML, lo analizaré y luego haré objetos que pasará a otra actividad. Estoy eligiendo Parcelable para esto.
¿Es Parcelable una buena opción? ¿Estoy haciendo todo correctamente? Realmente no estoy familiarizado con Parcelable. Mi ArrayList es de otra clase que hice dentro de esta clase. ¿Pasará correctamente esa ArrayList de objetos a la Parcela con no extender Parcelable y esas cosas?
import java.util.ArrayList;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.os.ParcelableCompat;
public class Question implements Parcelable{
String id;
String text;
String image;
ArrayList<Choices> CHOICES;
public Question(String id, String text, String image) {
super();
this.id = id;
this.text = text;
this.image = image;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
@Override
public String toString() {
return "Question [id=" + id + ", text=" + text + ", image=" + image
+ "]";
}
// Answer Choices class
class Choices {
boolean isCorrect;
String choice;
public Choices(boolean isCorrect, String choice) {
this.isCorrect = isCorrect;
this.choice = choice;
}
public String getChoice() {
return choice;
}
public boolean getIsCorrect() {
return isCorrect;
}
@Override
public String toString() {
return "Choices [isCorrect=" + isCorrect + ", choice=" + choice
+ "]";
}
}
public static final Parcelable.Creator<Question> CREATOR = new Parcelable.Creator<Question>() {
@Override
public Question createFromParcel(Parcel in) {
return new Question(in);
}
@Override
public Question[] newArray(int size) {
return new Question[size];
}
};
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(text);
dest.writeString(image);
dest.writeList(CHOICES);
}
private Question(Parcel in) {
this.id = in.readString();
this.text = in.readString();
this.image = in.readString();
this.CHOICES = in.readArrayList(Choices.class.getClassLoader());
}
}
¡Gracias por cualquier ayuda!
Cree un nuevo archivo java para "Opciones" e implemente "Parcelable". Si no implementa parcelable, obtendrá una excepción en tiempo de ejecución (No se puede hacer Marshal). Así que usa el siguiente código:
public class Choices implements Parcelable{
boolean isCorrect;
String choice;
public Choices(boolean isCorrect, String choice) {
this.isCorrect = isCorrect;
this.choice = choice;
}
//Create getters and setters
protected Choices(Parcel in) {
isCorrect = in.readByte() != 0;
choice = in.readString();
}
public static final Creator<Choices> CREATOR = new Creator<Choices>() {
@Override
public Choices createFromParcel(Parcel in) {
return new Choices(in);
}
@Override
public Choices[] newArray(int size) {
return new Choices[size];
}
};
@Override
public String toString() {
return "Choices [isCorrect=" + isCorrect + ", choice=" + choice
+ "]";
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeByte((byte) (isCorrect ? 1 : 0));
dest.writeString(choice);
}
}
Como se mencionó en la respuesta anterior de @ G.Blake, debe hacer que Choices Parcelable y Android sepa cómo parcelar ArrayLists of Parcelables
Lo tienes casi, pero no del todo, cierto. La clase de pregunta parece casi correctamente parcelable. Lo único que no funciona es parcelar la matriz de opciones.
Hay dos maneras de hacerlo:
- Hacer elecciones parcelables. Tendrás que agregar todos los métodos requeridos, y el CREADOR. Porque Android sabe cómo parcelar ArrayLists de Parcelables, esto funcionará.
- Haga que la parcelación de la matriz de opciones forme parte de la parcelación de la pregunta. Para hacer esto, probablemente empujaría el tamaño de la matriz en la Parcela, y luego pasaría por encima de las Opciones, presionando sus valores. En el otro extremo, primero leería el conteo y luego leería los valores para cada opción, creando cada uno e insertándolo en la nueva pregunta.
Si necesita pasar un ArrayList
entre las actividades, también me gustaría implementar Parcelable
, ya que no hay otra forma, supongo. Sin embargo, no creo que necesites tanto de captadores como de preparadores. Aquí está su clase de Question
que implementa Parcelable
:
public class Question implements Parcelable {
public String id;
public String text;
public String image;
public ArrayList<Choice> choices;
/**
* Constructs a Question from values
*/
public Question (String id, String text, String image, ArrayList<Choice> choices) {
this.id = id;
this.text = text;
this.image = image;
this.choices = choices;
}
/**
* Constructs a Question from a Parcel
* @param parcel Source Parcel
*/
public Question (Parcel parcel) {
this.id = parcel.readString();
this.text = parcel.readString();
this.image = parcel.readString();
this.choices = parcel.readArrayList(null);
}
@Override
public int describeContents() {
return 0;
}
// Required method to write to Parcel
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(text);
dest.writeString(image);
dest.writeList(choices);
}
// Method to recreate a Question from a Parcel
public static Creator<Question> CREATOR = new Creator<Question>() {
@Override
public Question createFromParcel(Parcel source) {
return new Question(source);
}
@Override
public Question[] newArray(int size) {
return new Question[size];
}
};
}
Utilizar:
in.createTypedArrayList(Product.CREATOR)
En el constructor que toma un objeto Parable como param.
En el método writeToParcel use dest.writeTypedList(product);