kotlin,如何使 hashMap 可打包

kotlin, how to make a hashMap parcelable

有一个变量是hashMap<IntRange, String>,需要把bundle作为parcelable放在onSaveStateInstance()/onCreateView()中保存和恢复:

val map: HashMap<IntRange, String>? = hashMapOf(IntRange(0, 4) to "x", IntRange(5, -1) to "y")

并做

//saving:
outState.putParcelable("saved_map", map)

...
//retrieving: 
val map = bundle.getParcelable("saved_map")

尽管如此,我还是建议使用包装器 class,因为它在 Kotlin 中比在 Java 中简单得多。 @Parcelize supports HashMap,问题是它不支持 IntRange(或者至少没有列出)。但是根据那里的例子,这似乎应该可行:

object IntRangeParceler : Parceler<IntRange> {
    override fun create(parcel: Parcel) = IntRange(parcel.readInt(), parcel.readInt())

    override fun IntRange.write(parcel: Parcel, flags: Int) {
        parcel.writeInt(value, start)
        parcel.writeInt(value, endInclusive)
    }
}

@Parcelize
@TypeParceler<IntRange, IntRangeParceler>()
class IntRangeStringMap(val value: HashMap<IntRange, String>)

你的电话变成了

outState.putParcelable("saved_map", IntRangeStringMap(map))
val map = bundle.getParcelable("saved_map").value

您甚至可以通过添加扩展功能让它看起来像您想要的样子。

根据@Alexey Romanov 的回答,得到了一个可用的版本

我改为制作可打包的包裹ArrayList<Pair<IntRange, String>>

object IntRangeParceler : Parceler<IntRange> {
    override fun create(parcel: Parcel) = IntRange(parcel.readInt(), parcel.readInt())

    override fun IntRange.write(parcel: Parcel, flags: Int) {
        parcel.writeInt(first)
        parcel.writeInt(last)
    }
}

object PairParceler : Parceler<Pair<IntRange, String>> {
    override fun create(parcel: Parcel): Pair<IntRange, String> =
        Pair(IntRange(parcel.readInt(), parcel.readInt()), parcel.readString())

    override fun Pair<IntRange, String>.write(parcel: Parcel, flags: Int) {
        parcel.writeInt(first.first)
        parcel.writeInt(first.last)
        parcel.writeString(second)
    }
}

@Parcelize
@TypeParceler<IntRange, IntRangeParceler>()
@TypeParceler<Pair<IntRange, String>, PairParceler>()
class IntRangeStringMap(val value:  ArrayList<Pair<IntRange, String>>) : Parcelable