ViewModel во фрагменте очищает значения при повороте экрана

Думаю, мне здесь не хватает чего-то очевидного, но ... Я храню данные в uiModel в классе DiaryViewModel, и, поскольку я использую компоненты архитектуры, я ожидаю, что данные будут сохранены при повороте экрана - но это не так. Я не понимаю почему.

Вот урезанный фрагмент

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 при повороте экрана.


comment
Какую версию вспомогательных библиотек вы используете? v26.1.0 включает поддержку Lifecycles (хотя не уверен, что это может быть причиной проблемы, которую вы видите)   -  person John O'Reilly    schedule 08.01.2018
comment
@ JohnO'Reilly 27.0.2. Я также читал, что это может быть проблема, но она была исправлена ​​в версии 26. Думаю, я столкнулся с чем-то другим.   -  person Algar    schedule 08.01.2018
comment
Это может быть связано с жизненным циклом фрагмента ... не обязательно решение само по себе, но обычно я передаю activity в ViewModelProviders.of(), но вам также необходимо проверить, что это имеет смысл для вашего конкретного варианта использования (пример это показано в developer.android.com/topic/libraries/architecture. /)   -  person John O'Reilly    schedule 08.01.2018
comment
Действительно. Я пробовал это, но это не сработало: / Без разницы.   -  person Algar    schedule 08.01.2018


Ответы (1)


Проблема заключалась в том, как операция обрабатывала создание фрагмента. 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()
    }
}
person Algar    schedule 10.01.2018