https://kotlinlang.org logo
#feed
Title
# feed
s

satyan

12/08/2020, 7:55 PM
Hey 👋 I just published my first article on migrating from LiveData to StateFlow https://fabernovel.github.io/2020-12-07/android-from-livedata-to-flows Feel free if you have feedbacks to hit me on my Twitter 😉
👏 3
👌 1
🦜 1
👀 2
d

Daniel

12/09/2020, 10:18 PM
Thank you for the article! How does StateFlow behave when the screen is recrated (rotation)? Also if the answer is: The value is observed again, how would it be possible to make a SingleLiveDataEvent with StateFlow? With other words: A value wich is really only observed one time and then consumed
a

allan.conda

12/10/2020, 9:55 AM
Oh, just in time, I’m literally doing this right now. Seems there’s no info about savedStateHandle? That’s kinda the blocker for me right now.
s

satyan

12/10/2020, 3:41 PM
@Daniel
How does StateFlow behave when the screen is recrated (rotation)?
Also if the answer is: The value is observed again, how would it be possible to make a SingleLiveDataEvent with StateFlow? With other words: A value wich is really only observed one time and then consumed
I had a part about SingleLiveEvent initially, but it was going to be too long. You can use a SharedFlow instead of a StateFlow On collect, a SharedFlow will emits its replay cache then emit the next values, so you can use a SharedFlow with a replay cache of 0
Copy code
class MyViewModel {
  private val _toast = MutableSharedFlow<String>() // by default replay cache is 0
val toast: SharedFlow<String> = _toast

  fun foo() {
    viewModelScope.launch {
      // suspend until collected
      _toast.emit("Hello")
}
  }
}
On configuration changes. the Stateflow value will be collected again yes
@allan.conda
Oh, just in time, I’m literally doing this right now.
Seems there’s no info about savedStateHandle? That’s kinda the blocker for me right now.
What do you mean ? I used savedStateHandle to save data but it’s only going to be use initially to restore the state.
Copy code
class MyViewModel (savedStateHandle: SavedStateHandle) {
    val _state = MutableStateFlow(restoreState())
    val state: StateFlow<State> = _state

    private fun restoreState(): State {
       return savedStateHandle.get(KEY) ?: INITIAL_STATE
    }
}
⚠️ If your state is big, you should only save part of it and restore the full state. For example, if your state is a paginated list, instead of saving the whole list, you could save the current page/token and then restore the items using it
a

allan.conda

12/10/2020, 4:10 PM
How do you save it? restoring is easy
I’m aware about the gotcha about large lists
s

satyan

12/10/2020, 4:21 PM
When you’re updating the state, you can save the relevant part to the savedStateHandle:
Copy code
fun foo() {
  viewmodelScope.launch {
    val user = userRepository.getUser(id)
     _state.value = mapper.mapState(user)   savedStateHandle[KEY] = user
  }
}
⚠️ You can only save types that can be save to a bundle inside the savedStateHandle. So you could create a UserSavedState parcelable type
a

allan.conda

12/10/2020, 4:56 PM
I see, so you simply update the savedStateHandle as well whenever you assigned a new value
s

satyan

12/10/2020, 5:44 PM
Yep’ I’m only relying on savedStateHandle to save/restore a state not to hold the entire screen state.
a

allan.conda

12/10/2020, 5:56 PM
SavedStateHandle.getLiveData returns a MutableLiveData which you could update directly. I’m currently trying to come up with a similar api with MutableStateFlow.
d

Daniel

12/10/2020, 8:44 PM
Thank you! @satyan
2 Views