Search code examples
androidkotlinparcelablekotlin-android-extensions

How to use Parcel.readTypedList() along with @Parcelize from kotlin-android-extensions?


I'm running into a problem with implementing Parcelable-based state persistence in a View. Namely, as I need to implement the methods of BaseSavedState like this:

class SavedState : BaseSavedState {
    lateinit var myList: ArrayList<MyParcelable>

    constructor(superState: Parcelable) : super(superState) {}

    private constructor(parcel: Parcel) : super(parcel) {
        val listSize = parcel.readInt()
        val list = ArrayList<MyParcelable>(listSize)
        this.myList = parcel.readTypedList(list, /* needs MyParcelable.CREATOR */ )
    }

    override fun writeToParcel(out: Parcel, flags: Int) {
        super.writeToParcel(out, flags)
        out.writeInt(myList.size())
        out.writeTypedList(myList)
    }

    companion object {
        @JvmField
        val CREATOR: Parcelable.Creator<SavedState> = object : Parcelable.Creator<SavedState> {
            override fun createFromParcel(`in`: Parcel): SavedState {
                return SavedState(`in`)
            }

            override fun newArray(size: Int): Array<SavedState?> {
                return arrayOfNulls(size)
            }
        }
    }
}

However, as you can see, I can't seem to use Parcel.readTypedList() because it needs both the typed list, and the parcelable's CREATOR field!

Classes marked like:

@Parcelize
data class MyParcelable(val someData: String): Parcelable {
}

Do not have CREATORs, in fact, if you try to implement, it says:

'CREATOR' definition is not allowed. Use 'Parceler' companion object instead.

I do not want a Parceler companion object, I need a CREATOR!

I also kinda don't want to write the Parcelable implementation by hand, so I might just make it Serializable and be like "whatever".


Does anyone know by chance how you can use Parcel.readTypedList() with @Parcelize-annotated Kotlin data class?


Solution

  • https://github.com/JetBrains/kotlin/commit/fc013c6b9f5f3083d06385803ff687dc9a6ab4f0#

    From Kotlin 1.6.21, we can use parcelableCreator() from

    import kotlinx.parcelize.parcelableCreator
    
    val dataClass = TestDataClass("someValue")
    val creator = parcelableCreator<TestDataClass>()
    val parcel: Parcel? = null
    parcel?.createTypedArrayList(creator) // Will compile