Sobes.tech
Middle

Come si possono implementare diversi stati in un'app Android usando classi sealed?

sobes.tech AI

Risposta dell'AI

Le classi sealed sono ideali per modellare un insieme finito di stati. Ogni stato secondario può contenere i propri dati unici.

Esempio:

sealed class UiState {
    object Loading : UiState() // Stato di caricamento senza dati
    data class Success(val data: List<Item>) : UiState() // Stato di successo con dati ricevuti
    data class Error(val message: String) : UiState() // Stato di errore con messaggio

    object Idle : UiState() // Stato iniziale o neutro
}

Applicazione:

  • In ViewModel, si può aggiornare MutableStateFlow (o altro tipo osservabile) con lo UiState corrente.
  • In Fragment o Activity, iscriversi alle modifiche di UiState e usare when per gestire ogni stato possibile, aggiornando di conseguenza l'UI.
// 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() // La tua funzione di recupero dati
                _uiState.value = UiState.Success(result)
            } catch (e: Exception) {
                _uiState.value = UiState.Error(e.message ?: "Errore sconosciuto")
            }
        }
    }
}
// In Fragment/Activity (usando Compose)
@Composable
fun MyScreen(viewModel: MyViewModel = viewModel()) {
    val uiState by viewModel.uiState.collectAsState()

    when (uiState) {
        UiState.Idle -> { /* Mostrare schermata iniziale */ }
        UiState.Loading -> { /* Mostrare indicatore di caricamento */ }
        is UiState.Success -> {
            val data = (uiState as UiState.Success).data
            // Mostrare i dati
        }
        is UiState.Error -> {
            val errorMessage = (uiState as UiState.Error).message
            // Mostrare messaggio di errore
        }
    }
}

Vantaggi:

  • Verifica completa: Il compilatore richiede di gestire tutte le sottoclassi della classe sealed nel when. Questo previene omissioni e aumenta l'affidabilità del codice.
  • Modellazione chiara degli stati: Definisce esplicitamente tutti gli stati possibili del componente UI.
  • Sicurezza di tipo: Ogni stato ha i propri dati, accessibili in modo sicuro senza bisogno di cast.
  • Migliore leggibilità: Il codice che utilizza classi sealed per gli stati diventa più comprensibile e facile da mantenere.

Questo approccio è particolarmente utile con Flow e Compose, ma funziona bene anche con LiveData e View Binding.