我可以将状态变量切换为可组合函数吗?

Ely*_*lye 2 android android-jetpack-compose

我有一个简单的可组合函数,如下所示

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            var isGrayScale by remember { mutableStateOf(false) }
            val colorChoice by remember(isGrayScale) {
                mutableStateOf(
                    if (isGrayScale)
                        ColorChoice(onColor = Color.White, offColor = Color.Black)
                    else
                        ColorChoice(onColor = Color.Green, offColor = Color.Red)
                )
            }
            Box(modifier = Modifier.fillMaxSize().background(colorChoice.color))
            Button(
                modifier = Modifier.padding(64.dp).fillMaxSize(),
                onClick = { colorChoice.toggle() }) {
                Text(
                    text = if (colorChoice.isOn) "On" else "Off",
                    color = colorChoice.color,
                    fontSize = 48.sp
                )
            }
            Switch(
                modifier = Modifier.padding(64.dp).fillMaxWidth(),
                checked = isGrayScale,
                onCheckedChange = {isGrayScale = !isGrayScale}
            )
        }
    }

    class ColorChoice(
        private val onColor: Color,
        private val offColor: Color
    ) {
        var isOn by mutableStateOf(false)
        var color by mutableStateOf(offColor)
        fun toggle() {
            isOn = !isOn
            color = if(isOn) {
                onColor
            } else {
                offColor
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该开关会将可组合函数引用更改为不同的状态变量。切换后,当状态变量发生变化时,可组合函数不再重新组合。

不支持更改可组合函数的状态变量吗?或者我做错了什么。

Ely*_*lye 7

经过一番调查后,显然问题在于,onClick = { colorChoice.toggle() }colorChoice更改时,lambda 仍然存储旧的“colorChoice”。

要更正它,请替换onClick = { colorChoice.toggle() }onClick = colorChoice::toggle. 这确保onClick将获得最新的colorChoice

完整代码如下

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            var isGrayScale by remember { mutableStateOf(false) }
            val colorChoice by remember(isGrayScale) {
                mutableStateOf(
                    if (isGrayScale)
                        ColorChoice(onColor = Color.White, offColor = Color.Black)
                    else
                        ColorChoice(onColor = Color.Green, offColor = Color.Red)
                )
            }
            Box(modifier = Modifier.fillMaxSize().background(colorChoice.color))
            Button(
                modifier = Modifier.padding(64.dp).fillMaxSize(),
                onClick = colorChoice::toggle) {
                Text(
                    text = if (colorChoice.isOn) "On" else "Off",
                    color = colorChoice.color,
                    fontSize = 48.sp
                )
            }
            Switch(
                modifier = Modifier.padding(64.dp).fillMaxWidth(),
                checked = isGrayScale,
                onCheckedChange = {isGrayScale = !isGrayScale}
            )
        }
    }

    class ColorChoice(
        private val onColor: Color,
        private val offColor: Color
    ) {
        var isOn by mutableStateOf(false)
        var color by mutableStateOf(offColor)
        fun toggle() {
            isOn = !isOn
            color = if(isOn) {
                onColor
            } else {
                offColor
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `::` 运算符是什么意思?为什么它“获得最新的colorChoice”? (2认同)
  • `::` 只是访问 lambda(将其视为函数指针) (2认同)