0

是否可以从 a 可组合的屏幕中设置 a 在FloatingActionButtonaonClick内部的值,该屏幕也在 a 内部?在我的示例中,我希望能够更改 FAB 的 onClick 以从屏幕可组合内的值 ( ) 进行一些计算,而无需将值提升到位于可组合( ) 的位置。ScaffoldNavHostScaffoldnameScaffoldMyActivity()

@Composable
fun MyActivity() {
    val navController = rememberNavController()

    Scaffold(
        floatingActionButton = {
            FloatingActionButton(onClick = { /* set this lambda from Screen1 */ }) { ... }
        }
    ) { paddingValues ->
        NavHost(
            navController = navController,
            startDestination = Screen.Screen1.route,
            modifier = Modifier.padding(paddingValues)
        ) {
            composable(route = Screen.Screen1.route) {
                Screen1()
            }
            ...
        }
    }
}

@Composable
fun Screen1() {
    var name by remember { mutableStateOf(TextFieldValue("") }

    TextField(value = name, onValueChange = { name = it })

    // Set FAB onClick to do some calculations on name without hoisting the variable
    setFabOnClick { name.calculate() }
}
4

1 回答 1

1

我不确定您为什么不想将此值放在顶视图中。如果您在示例中这样做,则更新文本不会导致重新组合MyActivity,只有Screen1- Compose 足够聪明地做到这一点。

在任何情况下,您都可以创建一个可变状态来存储处理程序并在Screen1. 我之所以使用LaunchedEffect,是因为更新状态是一种副作用,不应该直接从视图构造函数中完成,也不需要在每次重组时都这样做。

@Composable
fun Screen1(
    setFabOnClick: (() -> Unit) -> Unit,
) {
    var name by remember { mutableStateOf(TextFieldValue("")) }

    TextField(value = name, onValueChange = {name = it})

    LaunchedEffect(Unit) {
        setFabOnClick { println("$name") }
    }
}

@Composable
fun MyActivity() {
    val navController = rememberNavController()
    val (fabOnClick, setFabOnClick) = remember { mutableStateOf<(() -> Unit)?>(null) }

    Scaffold(
        floatingActionButton = {
            FloatingActionButton(onClick = {
                fabOnClick?.invoke()
            }) {
                Icon(Icons.Default.ReportProblem, null)
            }
        }
    ) { paddingValues ->
        NavHost(
            navController = navController,
            startDestination = Screen.Screen1.route,
            modifier = Modifier.padding(paddingValues)
        ) {
            composable(route = Screen.Screen1.route) {
                Screen1(setFabOnClick = setFabOnClick)
            }
        }
    }
}
于 2022-02-20T03:08:35.277 回答