https://kotlinlang.org logo
#compose
Title
# compose
h

Huan

01/19/2022, 6:41 PM
Hi I have a strange behavior using
Sealed class
,
when
and
flow
with
LazyColumn
🧵
I have the following sealed class:
sealed class DeviceInformationState {
object Initial : DeviceInformationState()
data class Success(val data: Data) : DeviceInformationState()
data class Error(val error: Error) : DeviceInformationState()
object Disconnected : DeviceInformationState()
}
The followings Mutable and StateFlows
private val deviceInformationMSF: MutableStateFlow<DeviceInformationState> by lazy {
MutableStateFlow(DeviceInformationState.Initial)
}
// Also tried without lazily initialization
internal val deviceInformationSF = deviceInformationMSF.asStateFlow()
... Then I collect the state in a Composeable function
val deviceInformationState by deviceInformationViewModel.deviceInformationSF.collectAsState()
when (deviceInformationState) {
DeviceInformationState.Disconnected -> {
ErrorScreen(message = stringResource(id = R.string.disconnected))
<http://Timber.wtf|Timber.wtf>("Disconnected")
}
DeviceInformationState.Initial -> {
<http://Timber.wtf|Timber.wtf>("Initial")
CircularProgressBar(stringResource(id = R.string.searching))
deviceInformationViewModel.manageCharacteristics(connected.bluetoothGatt, connected.bluetoothGattServiceList)
}
is DeviceInformationState.Success -> {
<http://Timber.wtf|Timber.wtf>("Success")
LazyColumn(
modifier = Modifier.padding(top = dimensionResource(id = R.dimen.app_service_section_title_padding_top)),
state = listState
){
DeviceInformationContent((deviceInformationState as DeviceInformationState.Success).deviceInformationUI)
}
}
is DeviceInformationState.Error -> {
<http://Timber.wtf|Timber.wtf>("Error")
ErrorScreen(message = (deviceInformationState as DeviceInformationState.Error).errorWithMessage.content)
}
}
I am getting a casting error: Disconnect cannot be cast to Success when I update the state to Disconnected when bluetooth is turned off:
deviceInformationMSF.value = DeviceInformationState.Disconnected
It is curious that If I replace
LazyColumn
by
Column
there is not any error and I received the Disconnect State in the when conditional. Also it works if I check if state is Success inside
item{}
section. But I don't understand why is Disconnect in item section due to it is inside a Success path in a
when
clausure
Copy code
is DeviceInformationState.Success -> {
    LazyColumn(
        modifier = Modifier.padding(top = dimensionResource(id = R.dimen.app_service_section_title_padding_top)),
        state = listState
    ) {
        item {
//Double check
 if (deviceInformationState is DeviceInformationState.Success) {
                DeviceInformationContent((deviceInformationState as DeviceInformationState.Success).deviceInformationUI)
            }
        }
    }
}
Any idea what is happening?
f

FunkyMuse

01/19/2022, 6:54 PM
Have you tried making your state flow not by lazy? private val deviceInformationMSF : MutableStateFlow<DeviceInformationState> = MutableStateFlow (DeviceInformationState.Initial)
h

Huan

01/19/2022, 6:56 PM
I have just try now. Apologizes for not writing this case in the message. I have updated the question
6 Views