The Code A is based a Android offical sample project here.
The Code A can display correct data in UI.
If I use Code B, I find that nothing is displayed.
It seems that _uiState=_uiState.copy(...)
doesn't make uiState
to notice UI that the data has changed in Code B.
What is wrong with Code B?
Code A
class InterestsViewModel(
private val interestsRepository: InterestsRepository
) : ViewModel() {
// UI state exposed to the UI
private var _uiState by mutableStateOf (InterestsUiState(loading = true)) //My
val uiState: InterestsUiState = _uiState //My
private fun refreshAll() {
_uiState .loading = true //My
viewModelScope.launch {
// Trigger repository requests in parallel
val topicsDeferred = async { interestsRepository.getTopics() }
val peopleDeferred = async { interestsRepository.getPeople() }
val publicationsDeferred = async { interestsRepository.getPublications() }
// Wait for all requests to finish
val topics = topicsDeferred.await().successOr(emptyList())
val people = peopleDeferred.await().successOr(emptyList())
val publications = publicationsDeferred.await().successOr(emptyList())
_uiState.loading=false //My
_uiState.topics=topics //My
_uiState.people=people //My
_uiState.publications=publications //My
}
}
}
fun rememberTabContent(interestsViewModel: InterestsViewModel): List<TabContent> {
// UiState of the InterestsScreen
val uiState = interestsViewModel.uiState //My
...
}
data class InterestsUiState(
var topics: List<InterestSection> = emptyList(), //My
var people: List<String> = emptyList(), //My
var publications: List<String> = emptyList(), //My
var loading: Boolean = false, //My
)
Code B
class InterestsViewModel(
private val interestsRepository: InterestsRepository
) : ViewModel() {
// UI state exposed to the UI
private var _uiState by mutableStateOf (InterestsUiState(loading = true))
val uiState: InterestsUiState = _uiState
private fun refreshAll() {
_uiState .loading = true
viewModelScope.launch {
// Trigger repository requests in parallel
val topicsDeferred = async { interestsRepository.getTopics() }
val peopleDeferred = async { interestsRepository.getPeople() }
val publicationsDeferred = async { interestsRepository.getPublications() }
// Wait for all requests to finish
val topics = topicsDeferred.await().successOr(emptyList())
val people = peopleDeferred.await().successOr(emptyList())
val publications = publicationsDeferred.await().successOr(emptyList())
_uiState=_uiState.copy(
loading = false,
topics = topics,
people = people,
publications = publications
)
}
}
}