4

I have a StateFlow that I want to use with Android data binding. As values in the flow I use a sealed type:

data class State(
    val idState: IdState
) : UiState

sealed class IdState {
    object NotAssigned : IdState()
    data class Assigned(val id: Id) : IdState()
}

@JvmInline
value class Id(val value: String)

I want to use it in the view like so:

  <com.google.android.material.textfield.TextInputLayout
            ...
            android:hint="@string/provide_client_id"
            android:text="@{viewModel.idText}">

So in the view model I have:

// uiState can be StateFlow or MutableStateFlow of UiState
val idText = uiState.map { state ->
    when (val idState = state.idState) {
        is UserIdState.Assigned -> idState.id.value
        UserIdState.NotAssigned -> "Not set"
    }
}

The problem occurs when I start the application:

Cannot find a setter for <com.google.android.material.textfield.TextInputLayout android:text> that accepts parameter type 'kotlinx.coroutines.flow.Flow<java.lang.String>'

The problem of course is with the map oparator which changes type from StateFlow to Flow which then cannot be used in Android data binding. Is there a way to map StateFlow values without converting it to Flow? I know that there is a stateIn operator of Flow, but I'm not quite sure if that is indented (StateFlow -> Flow -> StateFlow) and how to start it with viewModelScope while passing it to the view through ViewModel variable.

Jakub Licznerski
  • 1,008
  • 1
  • 17
  • 33

0 Answers0