首页 > 解决方案 > 如何为 List 实现 parcelable在科特林

问题描述

我正在尝试使以下级别的 Parcelable

data class Movie(
    @SerializedName("popularity")
    @Expose
    var popularity: Double,

    @SerializedName("vote_count")
    @Expose
    var voteCount: Int,

    @SerializedName("video")
    @Expose
    var video: Boolean,

    @SerializedName("poster_path")
    @Expose
    var posterPath: String?,

    @SerializedName("id")
    @Expose
    var id: Int,

    @SerializedName("adult")
    @Expose
    var adult: Boolean,

    @SerializedName("backdrop_path")
    @Expose
    var backdropPath: String?,

    @SerializedName("original_language")
    @Expose
    var originalLanguage: String?,

    @SerializedName("original_title")
    @Expose
    var originalTitle: String?,

    @SerializedName("genre_ids")
    @Expose
    var genreIds: List<Integer>,

    @SerializedName("title")
    @Expose
    var title: String?,

    @SerializedName("vote_average")
    @Expose
    var voteAverage: Double,

    @SerializedName("overview")
    @Expose
    var overview: String?,

    @SerializedName("release_date")
    @Expose
    var releaseDate: String?
) : Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.readDouble(),
        parcel.readInt(),
        parcel.readByte() != 0.toByte(),
        parcel.readString(),
        parcel.readInt(),
        parcel.readByte() != 0.toByte(),
        parcel.readString(),
        parcel.readString(),
        parcel.readString(),
        TODO("genreIds"),   <-------------- Which is generated by "Android Parcelable code generator" plugin
        parcel.readString(),
        parcel.readDouble(),
        parcel.readString(),
        parcel.readString()
    ) {
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeDouble(popularity)
        parcel.writeInt(voteCount)
        parcel.writeByte(if (video) 1 else 0)
        parcel.writeString(posterPath)
        parcel.writeInt(id)
        parcel.writeByte(if (adult) 1 else 0)
        parcel.writeString(backdropPath)
        parcel.writeString(originalLanguage)
        parcel.writeString(originalTitle)
        parcel.writeString(title)
        parcel.writeDouble(voteAverage)
        parcel.writeString(overview)
        parcel.writeString(releaseDate)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<Movie> {
        override fun createFromParcel(parcel: Parcel): Movie {
            return Movie(parcel)
        }

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

我遇到了一个错误,所以我从这个网站找到了解决方案How to implement parcelable for List<Long>

并完成如下

parcel.readList("genreIds",null),

但我仍然收到类似的错误

在此处输入图像描述

并且还按照这个页面 如何用 kotlin 包裹 List<Int> 我添加了如下扩展功能

fun Parcel.writeIntList(input:List<Int>) {
    writeInt(input.size) // Save number of elements.
    input.forEach(this::writeInt) // Save each element.
}

fun Parcel.createIntList() : List<Int> {
    val size = readInt()
    val output = ArrayList<Int>(size)
    for (i in 0 until size) {
        output.add(readInt())
    }
    return output
}

嗨@Eugen Pechanec 首先非常感谢您的帮助,根据您的建议,我已经完成了Int而不是Integer但在 readArrayList 中仍然出现错误

在此处输入图像描述

标签: androidkotlin

解决方案


在@ Eugen Pechanec 和@Networks 的帮助下,我找到了以下解决方案,

 data class Movie(
    @SerializedName("popularity")
    @Expose
    var popularity: Double,

    @SerializedName("vote_count")
    @Expose
    var voteCount: Int,

    @SerializedName("video")
    @Expose
    var video: Boolean,

    @SerializedName("poster_path")
    @Expose
    var posterPath: String?,

    @SerializedName("id")
    @Expose
    var id: Int,

    @SerializedName("adult")
    @Expose
    var adult: Boolean,

    @SerializedName("backdrop_path")
    @Expose
    var backdropPath: String?,

    @SerializedName("original_language")
    @Expose
    var originalLanguage: String?,

    @SerializedName("original_title")
    @Expose
    var originalTitle: String?,

    @SerializedName("genre_ids")
    @Ignore
    var genreIds: List<Int>,

    @SerializedName("title")
    @Expose
    var title: String?,

    @SerializedName("vote_average")
    @Expose
    var voteAverage: Double,

    @SerializedName("overview")
    @Expose
    var overview: String?,

    @SerializedName("release_date")
    @Expose
    var releaseDate: String?
) : Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.readDouble(),
        parcel.readInt(),
        parcel.readByte() != 0.toByte(),
        parcel.readString(),
        parcel.readInt(),
        parcel.readByte() != 0.toByte(),
        parcel.readString(),
        parcel.readString(),
        parcel.readString(),
        parcel.createIntList(),  //<-------------------------- change here
        parcel.readString(),
        parcel.readDouble(),
        parcel.readString(),
        parcel.readString()
    )
    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeDouble(popularity)
        parcel.writeInt(voteCount)
        parcel.writeByte(if (video) 1 else 0)
        parcel.writeString(posterPath)
        parcel.writeInt(id)
        parcel.writeByte(if (adult) 1 else 0)
        parcel.writeString(backdropPath)
        parcel.writeString(originalLanguage)
        parcel.writeString(originalTitle)
        parcel.writeIntList(genreIds) //<-------------------------- change here
        parcel.writeString(title)
        parcel.writeDouble(voteAverage)
        parcel.writeString(overview)
        parcel.writeString(releaseDate)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<Movie> {
        override fun createFromParcel(parcel: Parcel): Movie {
            return Movie(parcel)
        }

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


    }
}


            fun Parcel.createIntList(): List<Int> {
                val size = readInt()
                val output = ArrayList<Int>(size)
                for (i in 0 until size) {
                    output.add(readInt())
                }
                return output
            }

            fun Parcel.writeIntList(input:List<Int>) {
                writeInt(input.size) // Save number of elements.
                return input.forEach(this::writeInt) // Save each element.
            }

推荐阅读