為什麼我不能<T>直接在 Android Studio 中使用 ViewModel 中的 State?



代码A来自这里的官方示例项目。

InterestsViewModel定义uiStateStateFlow,collectAsState()在可组合函数rememberTabContent中将其转换为State<T>

我很奇怪为什么作者没有在InterestsViewModel中直接将uiState定义为State<T>,所以我写了代码b

代码B可以编译,也可以运行,但是屏幕上什么都不显示,代码B怎么了?

代码

data class InterestsUiState(
val topics: List<InterestSection> = emptyList(),
val people: List<String> = emptyList(),
val publications: List<String> = emptyList(),
val loading: Boolean = false,
)
class InterestsViewModel(
private val interestsRepository: InterestsRepository
) : ViewModel() {
// UI state exposed to the UI
private val _uiState = MutableStateFlow(InterestsUiState(loading = true))
val uiState: StateFlow<InterestsUiState> = _uiState.asStateFlow()
...
init {
refreshAll()
}

private fun refreshAll() {
_uiState.update { it.copy(loading = true) }
viewModelScope.launch {
...
// 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.update {
it.copy(
loading = false,
topics = topics,
people = people,
publications = publications
)
}
}
}

}

@Composable
fun rememberTabContent(interestsViewModel: InterestsViewModel): List<TabContent> {
// UiState of the InterestsScreen
val uiState by interestsViewModel.uiState.collectAsState()
... 
return listOf(topicsSection, peopleSection, publicationSection)
}

@Composable
fun InterestsRoute(
interestsViewModel: InterestsViewModel,
isExpandedScreen: Boolean,
openDrawer: () -> Unit,
scaffoldState: ScaffoldState = rememberScaffoldState()
) {
val tabContent = rememberTabContent(interestsViewModel)
val (currentSection, updateSection) = rememberSaveable {
mutableStateOf(tabContent.first().section)
}
InterestsScreen(
tabContent = tabContent,
currentSection = currentSection,
isExpandedScreen = isExpandedScreen,
onTabChange = updateSection,
openDrawer = openDrawer,
scaffoldState = scaffoldState
)
}

代码B

data class InterestsUiState(
val topics: List<InterestSection> = emptyList(),
val people: List<String> = emptyList(),
val publications: List<String> = emptyList(),
var loading: Boolean = false,
)

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
...

init {
refreshAll()
}
private fun refreshAll() {
_uiState.loading = true
viewModelScope.launch {
...
_uiState = _uiState.copy(
loading = false,
topics = topics,
people = people,
publications = publications
)
}
}
}
@Composable
fun rememberTabContent(interestsViewModel: InterestsViewModel): List<TabContent> {
// UiState of the InterestsScreen
val uiState = interestsViewModel.uiState
...
return listOf(topicsSection, peopleSection, publicationSection)
}

您在可组合val uiState: InterestsUiState = _uiState中使用的uiState不是状态,因此不响应更改。它只是一个普通的InterestsUiState,用_uiState的当前值初始化。要使其工作,您可以简单地公开_uiState的getter。

var uiState by mutableStateOf (InterestsUiState(loading = true))
private set

现在这个uiState只能从ViewModel内部修改,当你在Composable中使用它时,只要uiState的值改变,就会发生重组。

相关内容

  • 没有找到相关文章