And*_*er2 12 android kotlin android-jetpack-navigation android-jetpack-compose
我有一个登录屏幕,当登录成功并且视图模型更新可变状态变量时,我的期望是调用一个新的可组合函数来显示新屏幕,并删除登录屏幕。问题是,当Screen.AccountsScreen
显示新屏幕(又名)时,其内容不断闪烁/重绘,并且登录表单也会发生同样的情况,而该登录表单永远不会被破坏(我知道这一点是因为日志消息“Recomponing...”被无休止地打印) 。我认为发生这种情况是因为isLoginSuccessful
状态始终为真。看来我需要一个只能消耗一次的事件,这是正确的吗?如果是这样,我该怎么做?
LoginViewModel.kt
@HiltViewModel
class LoginViewModel @Inject constructor() : ViewModel() {
var isLoginSuccessful by mutableStateOf(false)
var errorMessage by mutableStateOf("")
fun onLoginClick(email: String, password:String) {
errorMessage = ""
if (credentialsValid(email, password)) {
isLoginSuccessful = true
} else {
errorMessage = "Email or password invalid"
isLoginSuccessful = false
}
}
}
Run Code Online (Sandbox Code Playgroud)
LoginScreen.kt
@Composable
fun loginScreen(
navController: NavController,
viewModel: LoginViewModel = hiltViewModel()
) {
println("Recomponing...")
// Here gos the code for the login form
if (viewModel.isLoginSuccessful) {
navController.navigate(Screen.AccountsScreen.route) {
popUpTo(Screen.LoginScreen.route) { inclusive = true }
}
}
}
Run Code Online (Sandbox Code Playgroud)
Phi*_*hov 19
复合导航会在转换过程中重新组合消失和出现的视图。这是预期的行为。
您在每次重组时调用导航。您的问题在于以下几行:
if (viewModel.isLoginSuccessful) {
navController.navigate(Screen.AccountsScreen.route) {
popUpTo(Screen.LoginScreen.route) { inclusive = true }
}
}
Run Code Online (Sandbox Code Playgroud)
您不应该直接从视图构建器更改状态。在这种情况下LaunchedEffect
应该使用:
if (viewModel.isLoginSuccessful) {
LaunchedEffect(Unit) {
navController.navigate(Screen.AccountsScreen.route) {
popUpTo(Screen.LoginScreen.route) { inclusive = true }
}
}
}
Run Code Online (Sandbox Code Playgroud)
查看副作用文档中的更多信息。
归档时间: |
|
查看次数: |
5933 次 |
最近记录: |