Middle
How can sealed classes be used to implement different states in an Android application?
sobes.tech AI
Answer from AI
Sealed classes are ideal for modeling a finite set of states. Each subclass state can contain its own unique data.
Example:
sealed class UiState {
object Loading : UiState() // Loading state without data
data class Success(val data: List<Item>) : UiState() // Successful state with received data
data class Error(val message: String) : UiState() // Error state with message
object Idle : UiState() // Initial or neutral state
}
Usage:
- In
ViewModel, you can update aMutableStateFlow(or another observable type) with the currentUiState. - In
FragmentorActivity, subscribe to changes inUiStateand handle each possible state withwhen, updating the UI accordingly.
// In ViewModel
class MyViewModel : ViewModel() {
private val _uiState = MutableStateFlow<UiState>(UiState.Idle)
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
fun loadData() {
viewModelScope.launch {
_uiState.value = UiState.Loading
try {
val result = fetchData() // Your data fetching function
_uiState.value = UiState.Success(result)
} catch (e: Exception) {
_uiState.value = UiState.Error(e.message ?: "Unknown error")
}
}
}
}
// In Fragment/Activity (using Compose)
@Composable
fun MyScreen(viewModel: MyViewModel = viewModel()) {
val uiState by viewModel.uiState.collectAsState()
when (uiState) {
UiState.Idle -> { /* Show initial screen */ }
UiState.Loading -> { /* Show loading indicator */ }
is UiState.Success -> {
val data = (uiState as UiState.Success).data
// Display data from data
}
is UiState.Error -> {
val errorMessage = (uiState as UiState.Error).message
// Show error message
}
}
}
Advantages:
- Exhaustive checking: The compiler requires handling all subclasses of the sealed class in
whenexpressions. This prevents missing states and increases code reliability. - Clear state modeling: Explicitly defines all possible UI component states.
- Type safety: Each state has its own data, accessed safely without casting.
- Improved readability: Code using sealed classes for states becomes more understandable and maintainable.
This approach is especially useful with Flow and Compose but also works well with LiveData and View Binding.