如何通过委托为 mutableState 使用但使其可传递给另一个函数?

时间:2021-03-30 12:01:08

标签: android android-jetpack-compose

我有一个可组合的功能,一个按钮可以切换显示文本并隐藏它

@Composable
fun Greeting() {
    Column {
        val toggleState = remember {
            mutableStateOf(false)
        }
        AnimatedVisibility(visible = toggleState.value) {
            Text(text = "Edit", fontSize = 64.sp)
        }
        ToggleButton(toggleState = toggleState) {}
    }
}

@Composable
fun ToggleButton(modifier: Modifier = Modifier,
                 toggleState: MutableState<Boolean>,
                 onToggle: (Boolean) -> Unit) {


    TextButton(
        modifier = modifier,
        onClick = {
            toggleState.value = !toggleState.value
            onToggle(toggleState.value)
        })
    { Text(text = if (toggleState.value) "Stop" else "Start") }
}

我不喜欢代码的一件事是val toggleState = remember { ... }
我更喜欢val toggleState by remember {...}

但是,如果我这样做,如下所示,我无法将 toggleState 传递给 ToggleButton,因为 ToggleButton 想要 mutableState<Boolean> 而不是 Boolean .因此它会出错。


@Composable
fun Greeting() {
    Column {
        val toggleState by remember {
            mutableStateOf(false)
        }
        AnimatedVisibility(visible = toggleState) {
            Text(text = "Edit", fontSize = 64.sp)
        }
        ToggleButton(toggleState = toggleState) {} // Here will have error
    }
}

@Composable
fun ToggleButton(modifier: Modifier = Modifier,
                 toggleState: MutableState<Boolean>,
                 onToggle: (Boolean) -> Unit) {


    TextButton(
        modifier = modifier,
        onClick = {
            toggleState.value = !toggleState.value
            onToggle(toggleState.value)
        })
    { Text(text = if (toggleState.value) "Stop" else "Start") }
}

如何在仍然使用 val toggleState by remember {...} 的同时修复上述错误?

1 个答案:

答案 0 :(得分:2)

Compose 中的状态提升是一种将状态移动到可组合的调用者以使可组合无状态的模式。 Jetpack Compose 中状态提升的一般模式是用两个参数替换状态变量:

  • value: T: 要显示的当前值
  • onValueChange: (T) -> Unit: 一个请求更改值的事件,其中 T 是建议的新值

你可以做类似的事情

// stateless composable is responsible 
@Composable
fun ToggleButton(modifier: Modifier = Modifier,
                 toggle: Boolean,
                 onToggleChange: () -> Unit) {
    
    TextButton(
        onClick = onToggleChange,
        modifier = modifier
    )
    { Text(text = if (toggle) "Stop" else "Start") }

}

@Composable
fun Greeting() {

        var toggleState by remember { mutableStateOf(false) }

        AnimatedVisibility(visible = toggleState) {
            Text(text = "Edit", fontSize = 64.sp)
        }
        ToggleButton(toggle = toggleState,
            onToggleChange = { toggleState = !toggleState }
        )
}

您还可以添加仅负责保持内部状态的相同状态可组合:

@Composable
fun ToggleButton(modifier: Modifier = Modifier) {

    var toggleState by remember { mutableStateOf(false) }

    ToggleButton(modifier,
        toggleState,
        onToggleChange = {
            toggleState = !toggleState
        },
    )
}