片段中的 ViewModel 清除屏幕旋转时的值

ViewModel in fragment clears values on screen rotation

猜猜我在这里遗漏了一些明显的东西但是...我将数据存储在 DiaryViewModel class 中的 uiModel 中,并且由于我使用架构组件 我希望通过屏幕旋转保留数据 - 但事实并非如此。我不知道为什么。

这是一个精简的片段

class DiaryFragment: Fragment() {
    private lateinit var viewModel: DiaryViewModel

    override onCreateView(...) {
        viewModel = ViewModelProviders.of(this).get(DiaryViewModel::class.java)
        viewModel.getModel().observe(this, Observer<DiaryUIModel> { uiModel ->
            render(uiModel)
        })
    }
}

以及相应的视图模型。

class DiaryViewModel: ViewModel() {
    private var uiModel: MutableLiveData<DiaryUIModel>? = null

    fun getModel(): LiveData<DiaryUIModel> {
        if (uiModel == null) {
            uiModel = MutableLiveData<DiaryUIModel>()
            uiModel?.value = DiaryUIModel()
        }

        return uiModel as MutableLiveData<DiaryUIModel>
    }
}

有人能看出这个简单示例中缺少什么吗?现在,旋转屏幕时 uiModel 设置为 null

问题在于 activity 如何处理片段创建。 MainActivity 总是在每次旋转时创建一个新片段,如

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    supportFragmentManager
        .beginTransaction()
        .replace(overlay.id, DiaryFragment.newInstance())
        .commit()
}

当然,在检查我们是否有保存的实例时效果更好,如

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    if (savedInstanceState == null) {
        supportFragmentManager
            .beginTransaction()
            .replace(overlay.id, DiaryFragment.newInstance())
            .commit()
    }
}