I am adding an answer to this old post just in case someone might find it useful.
I managed to do it as follows:
- Add the following dependency to your "build.gradle (Module: app)" file
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
- Add
savedState: SavedStateHandle
property to the constructor of the ViewModel
class SelectedTracksViewModel(private val savedState: SavedStateHandle) : ViewModel() {
companion object {
private const val SAVED_TRACK_INDEX = "savedTrackIndex"
}
private var trackIndex: Int
set(value) {
field = value
// Simply update the savedState every time your saved property changes
savedState.set(SAVED_TRACK_INDEX, value)
}
init {
trackIndex = savedState.get<Int>(SAVED_TRACK_INDEX) ?: 0
}
fun moveToNextTrack() {
trackIndex++
// Initially I was updating savedState here - now moved to setter
// Some more code here
}
}
Finally in the activity/fragment
private val selectedTracksViewModel: SelectedTracksViewModel by lazy {
ViewModelProvider(this).get(SelectedTracksViewModel::class.java)
}
And that's it. No need for SavedStateViewModelFactory
, simply add the savedState
property to your ViewModel
constructor and update it when tracked properties change. Everything else works as if you're not using savedState: SavedStateHandle
and this way is very similar to the traditional onSaveInstanceState(Bundle)
in activities/fragments.
Update: Initially I was updating savedState
after changing trackIndex
. This means one has to update savedState
every time saved properties are changed. This is a huge potential future bug if one forgets to add that line. A better and more robust pattern is to update the savedState
in the setter of the property.