I have an android project where I have a class. In that class is an ArrayList<Choices>
. I will be getting some XML, parsing it out, then making objects out of it which I will be passing to another activity. I'm choosing Parcelable for this.
Is Parcelable a good choice? Am I doing everything correctly? I'm not familiar really with Parcelable. My ArrayList is of another class that I made within this class. Will it properly pass that ArrayList of objects to the Parcel with it not extending Parcelable and stuff?
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());
}
}
Thanks for any help!
If you need to pass an ArrayList
between activities, then I'd go with implementing Parcelable
also, as there is no other way around I guess. However I don't think you will need that much of getters and setters. Here is your Question
class which implements 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]; } }; }
You have it almost, but not quite, right. The Question class looks nearly correctly Parcelable. The only thing that won't work is parcelling the array of Choices.
There are two ways that you could do it:
Use:
in.createTypedArrayList(Product.CREATOR)
In the constructor that takes a Parable object as a param.
In the writeToParcel method use dest.writeTypedList(product);
Create a new java file for "Choices" and implement "Parcelable". If you do not implement parcelable you will get run-time exception (Unable to Marshal). So use the code below :
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);
}
}
As mentioned in above answer by @G.Blake you need to make Choices Parcelable and Android knows how to parcel ArrayLists of Parcelables
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With