I\'m trying to use the new @Parcelize
annotation added with Kotlin 1.1.4 with a Realm objet containing a RealmList attribute.
@Parcelize
@RealmC
EDIT:
Using the power of Type Parcelers and @WriteWith
annotation, it is possible to create a RealmList type parceler that can handle this scenario for you:
With the following code:
fun Parcel.readRealmList(clazz: Class): RealmList?
where T : RealmModel,
T : Parcelable = when {
readInt() > 0 -> RealmList().also { list ->
repeat(readInt()) {
list.add(readParcelable(clazz.classLoader))
}
}
else -> null
}
fun Parcel.writeRealmList(realmList: RealmList?, clazz: Class)
where T : RealmModel,
T : Parcelable {
writeInt(when {
realmList == null -> 0
else -> 1
})
if (realmList != null) {
writeInt(realmList.size)
for (t in realmList) {
writeParcelable(t, 0)
}
}
}
You can define an interface like this:
interface RealmListParceler: Parceler?> where T: RealmModel, T: Parcelable {
override fun create(parcel: Parcel): RealmList? = parcel.readRealmList(clazz)
override fun RealmList?.write(parcel: Parcel, flags: Int) {
parcel.writeRealmList(this, clazz)
}
val clazz : Class
}
Where you'll need to create a specific parceler for the RealmList
like this:
object CarRealmListParceler: RealmListParceler {
override val clazz: Class
get() = Car::class.java
}
but with that, now you can do the following:
@Parcelize
@RealmClass
open class Garage(
var name: String? = null,
var cars: @WriteWith RealmList = RealmList()
) : Parcelable, RealmModel
And
@Parcelize
@RealmClass
open class Car(
..
): RealmModel, Parcelable {
...
}
This way you don't need to manually write the Parceler logic.
ORIGINAL ANSWER:
Following should work:
@Parcelize
open class Garage: RealmObject(), Parcelable {
var name: String? = null
var cars: RealmList? = null
companion object : Parceler {
override fun Garage.write(parcel: Parcel, flags: Int) {
parcel.writeNullableString(name)
parcel.writeRealmList(cars)
}
override fun create(parcel: Parcel): Garage = Garage().apply {
name = parcel.readNullableString()
cars = parcel.readRealmList()
}
}
}
As long as you also add following extension functions:
inline fun Parcel.writeRealmList(realmList: RealmList?)
where T : RealmModel,
T : Parcelable {
writeInt(when {
realmList == null -> 0
else -> 1
})
if (realmList != null) {
writeInt(realmList.size)
for (t in realmList) {
writeParcelable(t, 0)
}
}
}
inline fun Parcel.readRealmList(): RealmList?
where T : RealmModel,
T : Parcelable = when {
readInt() > 0 -> RealmList().also { list ->
repeat(readInt()) {
list.add(readParcelable(T::class.java.classLoader))
}
}
else -> null
}
and also
fun Parcel.writeNullableString(string: String?) {
writeInt(when {
string == null -> 0
else -> 1
})
if (string != null) {
writeString(string)
}
}
fun Parcel.readNullableString(): String? = when {
readInt() > 0 -> readString()
else -> null
}