Sobes.tech
Middle

Как с помощта на sealed класове да реализирате различни състояния в Android приложение?

sobes.tech AI

Отговор от AI

Затворените класове са идеални за моделиране на крайния набор от състояния. Всяко подкласово състояние може да съдържа свои уникални данни.

Пример:

sealed class UiState {
    object Loading : UiState() // Състояние на зареждане без данни
    data class Success(val data: List<Item>) : UiState() // Успешно състояние с получени данни
    data class Error(val message: String) : UiState() // Състояние на грешка с съобщение

    object Idle : UiState() // Начално или неутрално състояние
}

Използване:

  • В ViewModel може да се актуализира MutableStateFlow (или друг наблюдаван тип) с текущото UiState.
  • В Fragment или Activity да се абонирате за промените в UiState и чрез when да обработвате всяко възможно състояние, съответно актуализирайки UI.
// В 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() // Вашата функция за получаване на данни
                _uiState.value = UiState.Success(result)
            } catch (e: Exception) {
                _uiState.value = UiState.Error(e.message ?: "Неизвестна грешка")
            }
        }
    }
}
// В Fragment/Activity (използвайки Compose)
@Composable
fun MyScreen(viewModel: MyViewModel = viewModel()) {
    val uiState by viewModel.uiState.collectAsState()

    when (uiState) {
        UiState.Idle -> { /* Покажи началния екран */ }
        UiState.Loading -> { /* Покажи индикатор за зареждане */ }
        is UiState.Success -> {
            val data = (uiState as UiState.Success).data
            // Покажи данните
        }
        is UiState.Error -> {
            val errorMessage = (uiState as UiState.Error).message
            // Покажи съобщение за грешка
        }
    }
}

Предимства:

  • Пълна проверка: Компилаторът изисква обработка на всички подкласове на sealed класа в израза when. Това предотвратява пропускане на състояния и увеличава надеждността на кода.
  • Ясно моделиране на състояния: Определя ясно всички възможни състояния на UI компонента.
  • Типова безопасност: Всяко състояние има свои собствени данни, до които достъпът е безопасен, без необходимост от привеждане.
  • Подобрена четливост: Кодът, използващ sealed класове за състояния, става по-разбираем и лесен за поддръжка.

Този подход е особено полезен с Flow и Compose, но също така работи добре с LiveData и View Binding.