单击按钮时可组合项不会重新组合

ant*_*009 5 android android-jetpack-compose compose-recomposition

我有以下可组合函数。它是一个简单的登录屏幕,包含用户名、密码和提交按钮。

如果用户单击提交按钮时用户名或密码字段为空,则会显示小吃栏。但是,它在第​​一次点击时有效,但后续点击无效。

我认为单击按钮将强制可组合项重新组合,并且如果需要显示小吃栏,则 LaunchEffect 键将为 true。

@Composable
fun Login() {
    var username by remember { mutableStateOf("") }
    var password by remember { mutableStateOf("") }
    val scaffoldState = rememberScaffoldState()
    var shouldShowSnackBar by remember { mutableStateOf(false) }

    println("LoginScreen")

    LaunchedEffect(key1 = shouldShowSnackBar, block = {
        println("ShouldShowSnackBar")
        scaffoldState.snackbarHostState.showSnackbar(
            message = "Please enter a username and password",
            duration = SnackbarDuration.Short
        )
    })

   Scaffold(
        scaffoldState = scaffoldState
    ) {
        Column(modifier = Modifier.fillMaxWidth()) {
            OutlinedTextField(
                label = {
                    Text(text = "Username")
                },
                value = username,
                onValueChange = { newUsername ->
                    username = newUsername
                })

            OutlinedTextField(
                label = {
                    Text(text = "Password")
                },
                value = password,
                onValueChange = { newPassword ->
                    password = newPassword
                },
                visualTransformation = PasswordVisualTransformation())

            OutlinedButton(
                modifier = Modifier.fillMaxWidth(),
                onClick = {
                    shouldShowSnackBar = username.isEmpty() || password.isEmpty()
                    println("Button pressed: $shouldShowSnackBar")
                }) {
                Text(text = "Submit")
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Thr*_*ian 7

您看到的是预期的行为。在 jetpack Compose 中,要触发重组,State/MutableState 应该具有新值,并且在 State/MutableState 只读范围内触发组合。

您需要将 shouldShowSnackBar 设置为 false,并在 shouldShowSnackBar 为 true 时调用 LaunchedEffect 内的块。

LaunchedEffect(key1 = shouldShowSnackBar, block = {
    if(shouldShowSnackBar){
        println("ShouldShowSnackBar")
        scaffoldState.snackbarHostState.showSnackbar(
            message = "Please enter a username and password",
            duration = SnackbarDuration.Short
        )
        shouldShowSnackBar = false
    }
})
Run Code Online (Sandbox Code Playgroud)