Thread
#feed
    satyan

    satyan

    1 year ago
    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 😉
    Daniel

    Daniel

    1 year ago
    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

    1 year ago
    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.
    satyan

    satyan

    1 year ago
    @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
    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.
    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

    1 year ago
    How do you save it? restoring is easy
    I’m aware about the gotcha about large lists
    satyan

    satyan

    1 year ago
    When you’re updating the state, you can save the relevant part to the savedStateHandle:
    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

    1 year ago
    I see, so you simply update the savedStateHandle as well whenever you assigned a new value
    satyan

    satyan

    1 year ago
    Yep’ I’m only relying on savedStateHandle to save/restore a state not to hold the entire screen state.
    a

    allan.conda

    1 year ago
    SavedStateHandle.getLiveData returns a MutableLiveData which you could update directly. I’m currently trying to come up with a similar api with MutableStateFlow.
    Daniel

    Daniel

    1 year ago
    Thank you! @satyan