I call a View-Model method from a fragment. After screen rotation, my View-Model is called again. I need to don't destroy my created View-Model because of its values.
I know it is possible to handle it with Coroutines job.
Can you tell me if We have a better method for doing it?
ViewModel
private var _counterViewModelLiveData = MutableLiveData(0)
val counterViewModelLiveData
get() = _counterViewModelLiveData
private var job: Job? = null
fun startVmCounter() {
job?.cancel()
job = viewModelScope.launch {
while (true) {
delay(TimeUnit.SECONDS.toMillis(1))
_counterViewModelLiveData.value = _counterViewModelLiveData.value!! 1
}
}
}
Fragment
private fun viewModelSaveState(){
vm.startVmCounter()
vm.counterViewModelLiveData.observe(viewLifecycleOwner){
binding.txtViewmodelSaveStateCounter.text = it.toString()
}
}
Also, I know about SavedStateHandle, but I don't want to destroy my created ViewModel and fetch data again with SavedStateHandle.
CodePudding user response:
Assuming you are retrieving the ViewModel correctly, it shouldn't be recreated. From the code you posted the issue could be that you call viewModelSaveState
again after your Fragment is recreated. You want to call startVmCounter
only the first time the Fragment is created. To know if that's the case, you can check if the Bundle
you get (for example) in onViewCreated
is null. On the other hand, it's correct that you call vm.counterViewModelLiveData.observe
every time, because otherwise you won't get updates after recreation.
CodePudding user response:
Just place your code from viewModelSaveState()
into onCreateView()
or onViewCreated()
.
So the observation is only started when creating the Fragment and not when the configuration changed.