https://proandroiddev.com/loading-initi ... 747c20ce62
В этой статье автор, описывая преимущества и недостатки различных подходов к инициализации данных, приходит к выводу, что лучше всего это делать с помощью StateFlow. Я решил попробовать, учитывая, что использую обертку UiState в качестве общего состояния экрана.
Код: Выделить всё
sealed class UiState {
object Loading : UiState()
data class Error(val code: Int? = null, val message: String? = null) : UiState()
data class Content(val data: T) : UiState()
}
Код: Выделить всё
class MyRepo {
fun getMyData(): Flow {
return flow {
delay(1000)
emit(listOf("1", "2"))
}
}
}
class MyViewModel1(repo: MyRepo): ViewModel() {
data class ScreenStateUI(
val data: List = emptyList(),
val title: String = "Title"
)
private val _screenUiState: MutableStateFlow = MutableStateFlow(UiState.Loading)
val screenUiState: StateFlow = _screenUiState.asStateFlow()
init {
viewModelScope.launch {
repo.getMyData()
.map { UiState.Content(ScreenStateUI(data = it)) }
.collectLatest {
if (it is UiState.Content) {
_screenUiState.emit(
UiState.Content(data = it)
)
}
}
}
fun updateTitle(title: String) {
_screenUiState.update {
if (it is UiState.Content) {
it.copy(data = it.data.copy(title = title))
} else {
it
}
}
}
}
Теперь я изменил реализацию, чтобы удалить инициализацию в блоке инициализации и сделать все так, как как только пользовательский интерфейс подпишется на событие:
Код: Выделить всё
class MyRepo {
fun getMyData(): Flow {
return flow {
delay(1000)
emit(listOf("1", "2"))
}
}
}
class MyViewModel2(repo: MyRepo): ViewModel() {
data class ScreenStateUI(
val data: List = emptyList(),
val title: String = "Title"
)
val screenUiState: StateFlow by lazy {
repo.getMyData()
.map { UiState.Content(ScreenStateUI(data = it)) }
.onStart { emit(UiState.Loading) }
.catch { emit(UiState.Error(message = it.message)) }
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = UiState.Loading
)
}
fun updateTitle(title: String) {
...
}
}
Что мне здесь не хватает?
Подробнее здесь: https://stackoverflow.com/questions/792 ... shouldnt-t