为什么我的 UiState(stateflow 对象)在视图模型中更新后没有更新?

问题描述 投票:0回答:1

我通过

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],
)
android kotlin android-jetpack-compose android-viewmodel kotlin-stateflow
1个回答
1
投票

问题在于,每次屏幕重新组合时,您都会重新创建视图模型。

val viewModel = WhereToGoViewModel()

更新后,状态会发生重组。所以你的

WhereToGoApp
粗略地说再次执行,它重新创建视图模型并从那里获取状态。由于视图模型的新实例不知道有关先前状态更新的任何信息,因此它只是返回初始值。

© www.soinside.com 2019 - 2024. All rights reserved.