android Jetpack合成-忽略函数参数的合成

pnwntuvh  于 2022-11-27  发布在  Android
关注(0)|答案(1)|浏览(217)

我正在检查一个标记值,该值由一个更高级别的组件传递给我的可组合组件,但返回的值始终是初始值...
这是我的组件:

@Composable
fun Test(enabled: Boolean) {
    var expanded by remember { mutableStateOf(false) }

    ExposedDropdownMenuBox(
        expanded = expanded,
        onExpandedChange = {
            if (enabled) expanded = !expanded
            println("enabled is $enabled") //always prints the initial value of enabled
        }
    ) {
        OutlinedTextField(
            value = "value",
            onValueChange = { },
            modifier = Modifier.fillMaxWidth(),
            enabled = enabled,
            readOnly = true,
            label = { Text("Label") },
            trailingIcon = {
                ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
            },
        )

        ExposedDropdownMenu(
            expanded = expanded,
            onDismissRequest = {
                expanded = false
            }
        ) {
            DropdownMenuItem(
                onClick = {
                    expanded = false
                },
                text = {
                    Text("Content")
                }
            )
        }
    }
}

onExpandedChange中的程式码会忽略enabled的目前值。
例如,如果我运行下面的代码,我可以看到OutlinedTextField在2秒后更改为启用状态,但onExpandedChange将使用初始(旧)值enabled。

Surface(
    color = MaterialTheme.colorScheme.background
) {
    var flag by remember { mutableStateOf(false) }
    println("flag is $flag")

    LaunchedEffect(Unit) {
        delay(2000)
        flag = !flag
        println("flag is now $flag")
    }

    Test(flag)
}

我做错了什么?
编辑:如果我这样做的话,它会工作得很好:

@Composable
fun Test(enabled: Boolean) {
    var expanded by remember { mutableStateOf(false) }

    var enabledState by remember {
        mutableStateOf(enabled)
    }

    LaunchedEffect(enabled) {
        enabledState = enabled
    }

    ExposedDropdownMenuBox(
        expanded = expanded,
        onExpandedChange = {
            if (enabledState) expanded = !expanded
        }
    ) {
        OutlinedTextField(
            value = "value",
            onValueChange = { },
            modifier = Modifier.fillMaxWidth(),
            enabled = enabled,
            readOnly = true,
            label = { Text("Label") },
            trailingIcon = {
                ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
            },
        )

        ExposedDropdownMenu(
            expanded = expanded,
            onDismissRequest = {
                expanded = false
            }
        ) {
            DropdownMenuItem(
                onClick = {
                    expanded = false
                },
                text = {
                    Text("Content")
                }
            )
        }
    }
}

但如果我这么做的话就不管用了

@Composable
fun Test(enabled: Boolean) {
    var expanded by remember { mutableStateOf(false) }
    
    val enabledState by remember(enabled) {
        mutableStateOf(enabled)
    }

    ExposedDropdownMenuBox(
        expanded = expanded,
        onExpandedChange = {
            if (enabledState) expanded = !expanded
        }
    ) {
        OutlinedTextField(
            value = "value",
            onValueChange = { },
            modifier = Modifier.fillMaxWidth(),
            enabled = enabled,
            readOnly = true,
            label = { Text("Label") },
            trailingIcon = {
                ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded)
            },
        )

        ExposedDropdownMenu(
            expanded = expanded,
            onDismissRequest = {
                expanded = false
            }
        ) {
            DropdownMenuItem(
                onClick = {
                    expanded = false
                },
                text = {
                    Text("Content")
                }
            )
        }
    }
}

我也不知道为什么。

hi3rlvi2

hi3rlvi21#

重新组合不是忽略已更新的函数参数,而是忽略onExpandedChange的闭包。即使您通过更改remember键重新示例化MutableState,它也会保留MutableState的上一个示例。因此,您应该做的是更新MutableState的当前示例的值,而不是

val enabledState = remember(enabled) {
        mutableStateOf(enabled)
    }

您应该按照Bruno建议使用rememberUpdatedState,或者使用

val enabledState by remember {
    mutableStateOf(enabled)
}.apply {
    value = enabled
}

这就是rememberUpdatedState实现
Difference between remember and rememberUpdatedState in Jetpack Compose?

相关问题