-
-
Save mcxiaoke/f6eb2eb8049d1cfc352a to your computer and use it in GitHub Desktop.
How to use Parcelable in Kotlin v1.0.0-beta-4589
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Inline function to create Parcel Creator | |
| inline fun <reified T : Parcelable> createParcel(crossinline createFromParcel: (Parcel) -> T?): Parcelable.Creator<T> = | |
| object : Parcelable.Creator<T> { | |
| override fun createFromParcel(source: Parcel): T? = createFromParcel(source) | |
| override fun newArray(size: Int): Array<out T?> = arrayOfNulls(size) | |
| } | |
| // custom readParcelable to avoid reflection | |
| fun <T : Parcelable> Parcel.readParcelable(creator: Parcelable.Creator<T>): T? { | |
| if (readString() != null) return creator.createFromParcel(this) else return null | |
| } | |
| // IMPORTANT NOTE: | |
| // data class: does not support empty primary constructors and doesn't allow the use of lateinit modifier in the constructor. | |
| // That's why I ended up using regular classes and generating the equal and hash method with Android Studio. | |
| // I don't really like the idea of not using data classes but I prefer to avoid doing null checks while trying to use this models. | |
| // EXAMPLE with custom classes | |
| class User() : Parcelable { | |
| companion object { | |
| val CREATOR = createParcel { User(it) } | |
| } | |
| lateinit var _id: String | |
| lateinit var email: String | |
| lateinit var name: Name | |
| lateinit var phone: String | |
| lateinit var additional: Additional | |
| protected constructor(parcelIn: Parcel) : this() { | |
| this._id = parcelIn.readString() | |
| this.email = parcelIn.readString() | |
| this.name = parcelIn.readParcelable(Name.CREATOR) ?: Name() | |
| this.phone = parcelIn.readString() | |
| this.additional = parcelIn.readParcelable(Additional.CREATOR) ?: Additional() | |
| } | |
| override fun describeContents(): Int { | |
| return 0 | |
| } | |
| override fun writeToParcel(dest: Parcel, flags: Int) { | |
| dest.writeString(_id) | |
| dest.writeString(email) | |
| dest.writeParcelable(name, 0) | |
| dest.writeString(phone) | |
| dest.writeParcelable(additional, 0) | |
| } | |
| override fun equals(other: Any?): Boolean { | |
| if (this === other) return true | |
| if (other?.javaClass != javaClass) return false | |
| other as User | |
| if (_id != other._id) return false | |
| return true | |
| } | |
| override fun hashCode(): Int { | |
| return _id.hashCode() | |
| } | |
| } | |
| class Name() : Parcelable { | |
| companion object { | |
| val CREATOR = createParcel { Name(it) } | |
| } | |
| lateinit var first: String | |
| lateinit var last: String | |
| protected constructor(parcelIn: Parcel) : this() { | |
| this.first = parcelIn.readString() | |
| this.last = parcelIn.readString() | |
| } | |
| override fun describeContents(): Int { | |
| return 0 | |
| } | |
| override fun writeToParcel(dest: Parcel, flags: Int) { | |
| dest.writeString(first) | |
| dest.writeString(last) | |
| } | |
| override fun equals(other: Any?): Boolean { | |
| if (this === other) return true | |
| if (other?.javaClass != javaClass) return false | |
| other as Name | |
| if (first != other.first) return false | |
| if (last != other.last) return false | |
| return true | |
| } | |
| override fun hashCode(): Int { | |
| var result = first.hashCode() | |
| result += 31 * result + last.hashCode() | |
| return result | |
| } | |
| } | |
| class Additional() : Parcelable { | |
| companion object { | |
| val CREATOR = createParcel { Additional(it) } | |
| } | |
| lateinit var licensePlate: String | |
| protected constructor(parcelIn: Parcel) : this() { | |
| this.licensePlate = parcelIn.readString() | |
| } | |
| override fun writeToParcel(dest: Parcel, flags: Int) { | |
| dest.writeString(this.licensePlate) | |
| } | |
| override fun describeContents(): Int { | |
| return 0 | |
| } | |
| override fun equals(other: Any?): Boolean { | |
| if (this === other) return true | |
| if (other?.javaClass != javaClass) return false | |
| other as Additional | |
| if (licensePlate != other.licensePlate) return false | |
| return true | |
| } | |
| override fun hashCode(): Int { | |
| return licensePlate.hashCode() | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment