首页 > 解决方案 > 有没有一种优雅的方式来保存和恢复 Kotlin 中的视图状态?

问题描述

编写自定义视图以在 Android 的配置更改中保持其状态是冗长的,请查看仅保存一个字段状态的样板代码量:

private class SavedState : BaseSavedState {
        var amount: Int = 0

        constructor(parcel: Parcel) : super(parcel) {
            amount = parcel.readInt()
        }

        constructor (parcelable: Parcelable?) : super(parcelable)

        override fun writeToParcel(parcel: Parcel, flags: Int) {
            super.writeToParcel(parcel, flags)
            parcel.writeInt(amount)
        }

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

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

Android Extensions 插件提供了@Parcelize可用于自动生成实现的注解Parcelable,但在自定义视图的情况下,我们必须BaseSavedState从不直接从Parcelable.

所以,有这样的东西不会编译:

@Parcelize
data class SavedState(val isLoading: Boolean = false): BaseSavedState()

我想知道在自定义视图中是否有一种不那么冗长的方式来处理状态恢复。将不胜感激任何想法或建议。

标签: androidkotlinparcelable

解决方案


编写一个SaveState类是将所有需要保存的数据打包到一个类中的一种方法。另一种方法是覆盖onSaveInstanceState并将onRestoreInstanceState您的参数放在一个包中。这避免了你提到的样板。如果您有多个参数,只需使用带有注释的数据类并使用.(而不是本示例中的数量)@Parcelize保存该类。bundle.putParcelable也不要忘记设置isSaveEnabled为true。

init { isSaveEnabled = true }

...

override fun onSaveInstanceState(): Parcelable {
   val bundle = Bundle()
   bundle.putInt("amount", amount)
   bundle.putParcelable("superState", super.onSaveInstanceState())
   return bundle
}
override fun onRestoreInstanceState(state: Parcelable) {
 var viewState = state
 if (viewState is Bundle) {
   amount = viewState.getInt("amount", 0)
   viewState = viewState.getParcelable("superState")
 }
 super.onRestoreInstanceState(viewState)
}

推荐阅读