Pass ArrayList? implements Parcelable to Activity
The problem is in writing out to the parcel and reading in from the parcel ...
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(numOfSeason);
dest.writeInt(numOfEpisode);
}
private void readFromParcel(Parcel in) {
name = in.readString();
numOfSeason = in.readInt();
numOfEpisode = in.readInt();
}What you write out has to match what you read in...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent i = new Intent(this,SecondActivity.class);
ArrayList<testparcel> testing = new ArrayList<testparcel>();
i.putParcelableArrayListExtra("extraextra", testing);
startActivity(i);
}
/**********************************************/
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<testparcel> testing = this.getIntent().getParcelableArrayListExtra("extraextra");
}
}The above code is having onCreate() from two different activities. The first one launches the second one; and it works fine I was able to pull the parcelable without issue.
Help with passing ArrayList and parcelable Activity
I can see a number of problems here:
Why use addressParcelable? Why not make address implement Parcelable, and then use:
intent.putParcelableArrayListExtra( "addresses", addyExtras );
Your parcelable object must include a static CREATOR. See the documentation for details.
You are not actually adding any extras to the intent before you call
startActivity()
. See point 1 for a suggestion here.
I think that you will need to address all of these issues in order to get it working.
How to pass ArrayList of Objects from one to another activity using Intent in android?
It works well,
public class Question implements Serializable {
private int[] operands;
private int[] choices;
private int userAnswerIndex;
public Question(int[] operands, int[] choices) {
this.operands = operands;
this.choices = choices;
this.userAnswerIndex = -1;
}
public int[] getChoices() {
return choices;
}
public void setChoices(int[] choices) {
this.choices = choices;
}
public int[] getOperands() {
return operands;
}
public void setOperands(int[] operands) {
this.operands = operands;
}
public int getUserAnswerIndex() {
return userAnswerIndex;
}
public void setUserAnswerIndex(int userAnswerIndex) {
this.userAnswerIndex = userAnswerIndex;
}
public int getAnswer() {
int answer = 0;
for (int operand : operands) {
answer += operand;
}
return answer;
}
public boolean isCorrect() {
return getAnswer() == choices[this.userAnswerIndex];
}
public boolean hasAnswered() {
return userAnswerIndex != -1;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
// Question
builder.append("Question: ");
for(int operand : operands) {
builder.append(String.format("%d ", operand));
}
builder.append(System.getProperty("line.separator"));
// Choices
int answer = getAnswer();
for (int choice : choices) {
if (choice == answer) {
builder.append(String.format("%d (A) ", choice));
} else {
builder.append(String.format("%d ", choice));
}
}
return builder.toString();
}
}
In your Source Activity, use this :
List<Question> mQuestionList = new ArrayList<Question>;
mQuestionsList = QuestionBank.getQuestions();
mQuestionList.add(new Question(ops1, choices1));
Intent intent = new Intent(SourceActivity.this, TargetActivity.class);
intent.putExtra("QuestionListExtra", ArrayList<Question>mQuestionList);
In your Target Activity, use this :
List<Question> questions = new ArrayList<Question>();
questions = (ArrayList<Question>)getIntent().getSerializableExtra("QuestionListExtra");
Kotlin Passing ListArray to another Activity using Parcelable
Use something like this...
class Series() : Parcelable {
private var name: String? = null
private var numOfSeason: Int = 0
private var numOfEpisode: Int = 0
constructor(parcel: Parcel) : this() {
val data = arrayOfNulls<String>(3)
parcel.readStringArray(data)
this.name = data[0]
this.numOfSeason = Integer.parseInt(data[1])
this.numOfEpisode = Integer.parseInt(data[2])
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(name);
parcel.writeInt(numOfSeason);
parcel.writeInt(numOfEpisode);
}
private fun readFromParcel(parcel: Parcel){
name = parcel.readString()
numOfSeason = parcel.readInt()
numOfEpisode = parcel.readInt()
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Creator<Series> {
override fun createFromParcel(parcel: Parcel): Series {
return Series(parcel)
}
override fun newArray(size: Int): Array<Series?> {
return arrayOfNulls(size)
}
}
}
and then in your Activity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_activity)
val i = Intent(this, SecondActivity::class.java)
val testing = ArrayList<testparcel>()
i.putParcelableArrayListExtra("extraextra", testing)
startActivity(i)
}
class SecondActivity :Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.secondActivty_activity)
val testing = this.intent.getParcelableArrayListExtra<Parcelable>("extraextra")
}
}
intent.putExtra a list of Parcelable objects and enums
You don't need to make List parcelable. To put it, just use existing method.
final Intent i = new Intent(this,SecondActivity.class);
final ArrayList<Product> list = new ArrayList< Product >();
i.putParcelableArrayListExtra(PRODUCT_KEY, list);
startActivity(i);
To retrieve almost in the same way.
final ArrayList<Product> list = this.getIntent()
.getParcelableArrayListExtra(PRODUCT_KEY);
UPDATE
To answer you newer question. You cannot pass generic List
inside. Because by List
you could have different collection. To know system, which type to use you need to have explicit type.
// This will work.
final ArrayList<Department> departments = getSpecificDepartments();
intent.putParcelableArrayListExtra(DEPARTMENTS_KEY, departments);
Android Class Parcelable with ArrayList
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];
}
};
}
How do I pass arraylist of a custom object from one java class to another?
Serializable
and Parcelable
are not the same thing, although they serve the same purpose. This post contains an example of the Parcelable object.
The pattern employed should be followed for all Parcelable objects you want to create, changing only the writeToParcel
and AddValues(Parcel in)
methods. These two methods should mirror eachother, if writeToParcel
writes an int
then a string
, the constructor should read an int
then a string
Parcelable
public class AddValues implements Parcelable{
private int id;
private String value;
// Constructor
public AddValues (int id, String value){
this.id = id;
this.value= value;
}
// Parcelling part
public AddValues (Parcel in){
this.id = in.readInt();
this.value= in.readString();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(value);
}
public final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public AddValues createFromParcel(Parcel in) {
return new AddValues(in);
}
public AddValues[] newArray(int size) {
return new AddValues[size];
}
};
}
Adding the list to an Intent extra should be simple now
Put List extra
ArrayList<AddValue> list = new ArrayList<>();
Intent intent = new Intent(BluetoothLeService.this,HomePageFragment.class);
intent.putExtra("arg_key", list);
Get List extra
ArrayList<AddValues> list = (ArrayList<AddValues>) intent.getSerializableExtra("arg_key");
As an aside, you can use the Pair<Integer, String>
object instead of creating an AddValues
object. This doesn't affect the answer, but might be nice to know.
Related Topics
The Process of the Service Is Killed After the Application Is Removed from the Application Tray
Getintent() Extras Always Null
Android: How to Make an Activity Return Results to the Activity Which Calls It
How to Store SQLite Database Directly on Sdcard
How to Send JSON Object to Server Using Volley in Android
Upload an Image and Audio in One Request in Android
Wrong Requestcode in Onactivityresult
How to Call a Function After Delay in Kotlin
How to Add the Aidl File to Android Studio (From the In-App Billing Example)
No Good Example About Recyclerview and Staggeredgridlayoutmanager in Android Docs
How to Wrap the Height of a Viewpager to the Height of Its Current Fragment
Could Not Find Method Android() for Arguments
Horizontal Scrolling Grid View
Drawing Multiple Lines in Edittext E.G. Notepad