😽

【Android】Boolean とオブジェクトのリストを持つデータクラスの Parcelable を実装する

2021/06/22に公開

Parcelable について

  • 状態を一時的に保存して欲しいオブジェクトが実装すべきインターフェイス
  • Parcelableを実装したオブジェクトは、Intentを使ってActivity間でやり取り出来る

実装例

Noteというデータクラスを使ってParcelableを実装してみます。

data class Note(
    val id: Int,
    val title: String,
    val createdAt: Date,
    val isDeleted: Boolean,
    val pages: List<Page>
) : Parcelable {

    override fun describeContents(): Int = 0

    override fun writeToParcel(dest: Parcel?, flags: Int) {
        dest?.run {
            writeInt(id)
            writeString(title)
            writeSerializable(createdAt)
            writeInt(if (isDeleted) 1 else 0)
            writeList(pages)
        }
    }

    companion object {
        @JvmField
        val CREATOR = object : Parcelable.Creator<Note> {
            override fun createFromParcel(source: Parcel): Note = source.run {
                Note(
                    id = readInt(),
                    title = readString() ?: "",
                    createdAt = readSerializable() as Date,
                    isDeleted = (readInt() == 1),
                    pages = arrayListOf<Page>().apply {
                        readList(this, Page::class.java.classLoader)
                    }
                )
            }

            override fun newArray(size: Int): Array<Note?> = arrayOfNulls(size)
        }
    }
}

data class Page(
    val title: String,
    val content: String,
    val createdAt: Date
) : Serializable

isDeleted: Booleanの変換

Booleanを変換するために「readBoolean()」というメソッドが用意されていますが、このメソッドが「API Level 29」からしか使えません。

なので、以下のように「readInt()」を使ってBooleanに変換しています。

// 0 -> false, 1 -> true

// 書き込み
writeInt(if (isDeleted) 1 else 0)

// 読み取り
isDeleted = (readInt() == 1),

pages: List<Page>の変換

writeList()」と「readList()」を使います。

読み取りの時は、以下のようにして「kotlin.collections.ArrayList」に変換します。

arrayListOf<Page>().apply {
  readList(this, Page::class.java.classLoader)
}

Discussion