Reputation: 1703
I am trying to pass an object as a parameter from an activity to a fragment.
I already searched over hill and dale to find out how to do it, I tried many methods but none of them worked.
Here is what I tried :
// In my Activity, where I call my fragment
var bundle = Bundle()
bundle.putParcelable("restaurant", restaurant)
var fragment = Home2Fragment()
fragment.arguments = bundle
supportFragmentManager.beginTransaction().replace(R.id.content, fragment, FRAGMENT_HOME).commit()
My IDE (Android Studio) underline "restaurant" in bundle.putParcelable line, telling me a type mismatch. This is the same with the getArguments() methods, I get a type mismatch.
My class look like this :
@Parcel
class Establishment {
var title = ""
// More variables
fun loadFromJson(json: JsonObject) {
title = readString(json, TAG_TITLE)
// More API loads
}
companion object {
private const val TAG_TITLE = "title"
// More tags
}
}
I don't understand why my class is set as "Parcel" but is not recognized as a "Parcelable".
I am looking for an efficient way to pass parameters from an activity to a fragment.
Thanks a lot in advance.
EDIT :
As asked, I tried to make it as Serializable. I can't make it Serializable, as "Serializable" does not exists.
But I tried to make it "SerializedName", but "This annotation is not applicable to target 'class' "
Upvotes: 1
Views: 357
Reputation: 1703
So with your help I finally found out how to do this.
In my fragment, I modified my newInstance() fun :
companion object {
fun newInstance(restaurant : Establishment) : Home2Fragment {
val fragment = Home2Fragment()
val args = Bundle()
args.putParcelable("restaurant", restaurant)
fragment.arguments = args
return (fragment)
}
}
This was not very difficult, it was before as my IDE was telling me that my object "Establishment" was not a Parcelable Object.
So the real problem was to set "Establishment" as a Parcelable Object.
It gave me hard time so I decided to use Parcelable Generator plugin, as adviced by TpoM6oH.
My class Establishment now look like this :
@Parcel
class Establishment() : Parcelable {
var title = ""
// More var
fun CREATOR(): Parcelable.Creator<Establishment> = object : Parcelable.Creator<Establishment> {
override fun createFromParcel(p0: android.os.Parcel?): Establishment {
return Establishment()
}
override fun newArray(p0: Int): Array<Establishment> {
return null as Array<Establishment>
}
}
constructor(parcel: android.os.Parcel) : this() {
this = parcel.readString()
// More var
}
fun loadFromJson(json: JsonObject) {
title = readString(json, TAG_TITLE)
// More load from API
}
companion object {
private const val TAG_TITLE = "title"
}
override fun writeToParcel(parcel: android.os.Parcel, flags: Int) {
parcel.writeString(title)
// More var
}
override fun describeContents() : Int {
return 0
}
}
The plugin Parcelable Generator added some mysterious functions in my class, and "Establishment" (line 2) is still a problem in my IDE opinion ("This class implements Parcelable but does not provide a CREATOR field").
But the code DOES compile ! And it is working !
Thanks everyone for your advice.
Upvotes: 0
Reputation: 7011
Your class should implement Parcelable this way:
class Establishment(val title: String) : Parcelable {
private constructor(p: Parcel) : this(
title = p.readString(),
override fun writeToParcel(dest: Parcel, flags: Int) {
dest.writeString(title)
}
override fun describeContents() = 0
companion object {
@JvmField val CREATOR = object : Parcelable.Creator<Establishment> {
override fun createFromParcel(parcel: Parcel) = Establishment(parcel)
override fun newArray(size: Int) = arrayOfNulls<Establishment>(size)
}
}
fun loadFromJson(json: JsonObject) {
title = readString(json, TAG_TITLE)
// More API loads
}
}
Upvotes: 3