Tema
/
Mobiliosios programėlės KOTLIN
Pamoka 3 / 14 Būsena ir ViewModel (MVI) ~50 min

Sukurk krepšelio MVI — 4 failai (data → presentation)

Šis žingsnis sukuria keturis krepšelio failus. Jie kodo stulpelyje kaip skirtukai, tvarka data → presentation — kurk iš viršaus į apačią, nes kiekvienas priklauso nuo ankstesnio. Sukursi ViewModel pirmą — gausi keturias raudonas kompiliavimo klaidas ir jokio supratimo kodėl.

1. CartItem.kt (data) — viena krepšelio eilutė: pica plius kiekis. Nieko daugiau.

2. CartEvent.kt (presentation) — viskas, ką vartotojas gali padaryti, kaip sealed interface:

sealed interface CartEvent {
    data class AddItem(val menuItem: MenuItem) : CartEvent
    data class IncreaseQuantity(val menuItem: MenuItem) : CartEvent
    // …po vieną atvejį kiekvienam veiksmui
}

3. CartUiState.kt (presentation) — visa būsena. Esminė mintis: suma išvestinė, ne saugoma:

val totalPrice: Double get() = items.sumOf { it.menuItem.price * it.quantity }

Ji apskaičiuojama iš items kiekvieną kartą skaitant, todėl niekada negali „prasilenkti" su tikru krepšeliu.

4. CartViewModel.kt (presentation) — logika. onEvent(...) priima kiekvieną įvykį ir per _uiState.update { it.copy(...) } pagamina naują būseną. MutableStateFlow privatus (_uiState); išorei atskleidžiam tik skaityti (uiState).

Patikrink. Projektas kompiliuojasi be klaidų. Loginį veikimą galima pasitikrinti mintyse: AddItem(Margherita) du kartus → items turi vieną CartItem su quantity = 2, totalPrice = 17.00.

Spąstai. MVI būsena — nekintama (immutable). Nepamėgink laikyti MutableList ir jo keisti vietoje:

// BLOGAI — Compose NEpersipieš:
_uiState.value.items.add(CartItem(item, 1))   // keiti tą patį sąrašą

StateFlow praneša apie pokytį tik kai pasikeičia reikšmė (nauja copy). Jei keiti seną objektą vietoje, nuoroda ta pati → UI nieko nepastebi, suma neatsinaujina. Visada gamink naują būseną: _uiState.update { it.copy(items = newItems) }.