我通过
updateSelectedCategory(category = selectedCategory)
函数更新模型中的uiState,我检查了视图模型中的日志,一切都很好,它已更新。但是,当我在 WhehereToGoApp
compose 函数中检查此参数时,参数 uiState.currentPlacesList
没有更新,为什么?我认为我没有正确收集状态,但我不知道如何修复它。
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun WhereToGoApp() {
val viewModel = WhereToGoViewModel()
val uiState = viewModel.uiState.collectAsState()
val navController = rememberNavController()
val isCategoryScreen = (navController.currentBackStackEntryAsState().value?.destination?.route
?: WhereToGoAppScreens.Categories.name) == WhereToGoAppScreens.Categories.name
Scaffold(
topBar = {
WhereToGoAppBar( // todo
title = if (isCategoryScreen) {
"Select Category "
} else {
uiState.value.selectedCategory.title
},
showNavigationIcon = !isCategoryScreen,
onBackButtonClick = {
navController.navigateUp()
}
)
}
) { contentPadding ->
NavHost(
navController = navController,
startDestination = WhereToGoAppScreens.Categories.name
) {
composable(route = WhereToGoAppScreens.Categories.name) {
CategoriesScreen(
categoryList = LocalDataProvider.getCategories(),
onItemClick = { selectedCategory ->
viewModel.updateSelectedCategory(category = selectedCategory)
navController.navigate(WhereToGoAppScreens.Places.name)
},
paddingValues = contentPadding
)
}
composable(route = WhereToGoAppScreens.Places.name) {
PlacesScreen(
places = uiState.value.currentPlacesList,
onItemClick = { selectedPlace ->
viewModel.updateSelectedPlace(place = selectedPlace)
navController.navigate(WhereToGoAppScreens.PlaceDetails.name)
},
paddingValues = contentPadding
)
}
composable(route = WhereToGoAppScreens.PlaceDetails.name) {
PlaceDetailScreen(
place = uiState.value.selectedPlace,
paddingValues = contentPadding
)
}
}
}
}
ViewModel代码
class WhereToGoViewModel : ViewModel() {
private val _uiState = MutableStateFlow(WhereToGoUiState())
val uiState: StateFlow<WhereToGoUiState> = _uiState.asStateFlow()
fun updateSelectedCategory(category: Category) {
_uiState.update { uiState ->
uiState.copy(
selectedCategory = category,
currentPlacesList = LocalDataProvider.getPlaces().filter {
it.category == category
}
)
}
}
fun updateSelectedPlace(place: Place) {
_uiState.update {
_uiState.value.copy(
selectedPlace = place
)
}
}
}
data class WhereToGoUiState(
val selectedCategory: Category = Category.NightClub,
val currentPlacesList: List<Place> = emptyList(),
val selectedPlace: Place = LocalDataProvider.getPlaces()[0],
)
问题在于,每次屏幕重新组合时,您都会重新创建视图模型。
val viewModel = WhereToGoViewModel()
更新后,状态会发生重组。所以你的
WhereToGoApp
粗略地说再次执行,它重新创建视图模型并从那里获取状态。由于视图模型的新实例不知道有关先前状态更新的任何信息,因此它只是返回初始值。