我正在构建一个用于解决问卷的应用程序。该应用程序具有三个屏幕MainMenuView
:QuestionnaireView
和SettingsView
。用户可以从 MainMenu 输入QuestionnaireView
,但是除非userId尚未提交(我将userId保存在 SharedPreferences 中),否则SettingsView
他们无法输入。QuestionnaireView
SettingsView
在我MainMenuViewModel
创建isUserIdFilled
的 mutableState 中,它指示(通过检查checkUserIdFilled()
)是否已提交userId 。
class MainMenuViewModel constructor(val getUserId: GetUserIdUseCase) : ViewModel() {
var isUserIdFilled by mutableStateOf(false)
private set
init {
checkUserIdFilled()
}
fun checkUserIdFilled() {
if (getUserId().isNotEmpty()) {
isUserIdFilled = true
}
}
}
在 NavigationHost 中,我正在检查userId是否已提交并导航到SettingsView
or QuestionnaireView
。if ononQuestionnaireClick
工作并导航到SettingsView
如果userId尚未提交。但是,isUserIdFilled
状态没有更新(init inMainMenuViewModel
没有再次执行,因为 ViewModel 仍在后台堆栈中并且没有重新创建)并且我一直被重定向到SettingsView
(除非我重新启动应用程序)。所以我checkUserIdFilled()
在 NavHost 中添加了调用。但是,我不喜欢这种方法,因为它会改变 Composable 函数的状态。
@Composable
fun MyNavHost(navController: NavHostController, modifier: Modifier = Modifier) {
NavHost(
navController = navController,
startDestination = Screen.MainMenu.name,
modifier = modifier
) {
composable(Screen.MainMenu.name) {
val mainMenuViewModel = hiltViewModel<MainMenuViewModel>()
MainMenuView(
onQuestionnaireClick = {
// Is there a better way to do this and avoid the below call?
mainMenuViewModel.checkUserIdFilled()
if (mainMenuViewModel.isUserIdFilled)
navController.navigate(Screen.Questionnaire.name)
else {
navController.navigate(Screen.Settings.name)
}
},
onSettingsClick = { navController.navigate(Screen.Settings.name) },
mainMenuViewModel = mainMenuViewModel
)
}
composable(Screen.Questionnaire.name) {
val questionnaireViewModel = hiltViewModel<QuestionnaireViewModel>()
QuestionnaireView(questionnaireViewModel)
}
composable(Screen.Settings.name) {
val settingsViewModel = hiltViewModel<SettingsViewModel>()
// userId is submitted and saved to SharedPreferences here
SettingsView(settingsViewModel::onSubmitUserId, settingsViewModel)
}
}
}
有一个更好的方法吗?一旦以干净的方式提交了userIdisUserIdFilled
,如何更新?SettingsViewModel