I am totally new to sealed Interface
in Kotlin. I am trying to state management through sealed
in Android Kotlin. My main goal is when
I use the object of sealed
I don't want to inherit all children. I am not sure if sealed interface
is the right choice for me. All my code may be wrong, please correct me if I am wrong. Thanks.
sealed interface ConnectionUIState
sealed class BluetoothConnectionUIState {
object Initial : BluetoothConnectionUIState()
data class ScanningDevice(val storedDevice: SnapshotStateList<BluetoothDevice>? = null) : ConnectionUIState
}
I initialise the variable like this:
var uiState by mutableStateOf<BluetoothConnectionUIState>(BluetoothConnectionUIState.Initial)
private set
Now I am passing the uiState
variable in the function and using when
statement:
when (uiState) {
BluetoothConnectionUIState.ScanningDevice -> {
xuz()
}
}
why when
statement is giving error:
'when' expression must be exhaustive, add necessary 'Initial' branch or 'else' branch instead
Also this line is also giving me error: BluetoothConnectionUIState.ScanningDevice
in when
statement.
Error
Classifier 'ScanningDevice' does not have a companion object, and thus must be initialized here
If I am doing wrong here. Can you please elaborate of 2 point of this stack overflow. Thanks.
UPDATE
I did some changes:
sealed interface ConnectionUIState
sealed class BluetoothConnectionUIState {
object Initial : ConnectionUIState
data class ScanningDevice(val storedDevice: SnapshotStateList<BluetoothDevice>? = null) : BluetoothConnectionUIState()
}
I did success on when
statement that it's not complaining about Initial
:
when (uiState) {
is BluetoothConnectionUIState.ScanningDevice -> {
BluetoothPairContent(viewModel, tryAgainAction, openSettingAction, scanDeviceList)
}
}
That is my goal, but another problem raised that it gives error in uiState
initialise time:
var uiState by mutableStateOf<BluetoothConnectionUIState>(BluetoothConnectionUIState.Initial)
private set
**Error**
Type mismatch.
Required:
BluetoothConnectionUIState
Found:
BluetoothConnectionUIState.Initial
Again I am confused. Please guide me on this. Thanks
(I think you worked it out but just in case - you need
is
in yourwhen
to check if somethingis
a class. When comparing to anobject
you use equality, which can just be written as the value to match)Working off your update:
You've got this object and class nested inside
BluetoothConnectionUIState
, which means their fully qualified names are things likeBluetoothConnectionUIState.Initial
. But you don't actually have to nest them, you can do this:Now
Initial
andScanningDevice
aren't nested insideBluetoothConnectionUIState
, you just reference them directly. So what's the relationship between them now? Look at the constructors:Once you remove the nesting, you can see that
Initial
actually has no type relationship with the sealed class at all! It just happened to be located inside it. And that's why you can't put it in yourmutableStateOf
- it's not a BluetoothConnectionUIState.It's also why you were getting the must be exhaustive error in your original
when
block - you only had a branch checkingInitial
, which isn't part of the sealed class anyway. It works when you checkScanningDevice
, because that's the only member of the class - ifuiState
is aBluetoothConnectionUIState
, it must be aScanningDevice
.How you fix this is up to you - seems like you want those two things to be part of the same sealed class. Maybe you want
ConnectionUIState
to be the sealed class? Since that's what they both represent. And haveBluetoothConnectionUIState
be the interface that you can apply selectively to certain members of that sealed class?This overview might be a helpful read too!