在撰写层次结构中处理按钮点击的推荐方法是什么?我有一个列表,其中的项目旁边有一个编辑按钮。当用户点击按钮时,应用程序应将视图更改为该项目的编辑器。
我想我可以将点击处理函数向下传递到每个可组合项,但这似乎并不正确,因为其他可组合项只会将其转发到更深的可组合项。
此类情况是否有既定的模式?
@Composable
fun App() {
var isBrowsing = remember { mutableStateOf(true) }
if (isBrowsing)
Browser() // <-- somewhere inside there is the "Edit" button
} else {
Editor() // <-- somewhere inside there is the "Exit" button
}
}
请查看文档中的此部分有关
CompositionLocal
的内容。它的目标是使某些值在整个 Composable 层次结构中可用,而无需在每个 Composable 中显式传递这些值。
在示例中,这主要用于与主题相关的变量。但您可以尝试将其调整为与回调函数一起使用。但是,请注意,我不确定这是否是推荐的方法,并且这完全是一个实验,我不知道它是否会起作用。请尝试以下代码并报告是否有效:
首先,将此变量放置在可组合函数之外的某个位置:
val EditorCallback = compositionLocalOf<(Boolean) -> Unit> {}
然后将此代码添加到您的可组合项中:
@Composable
fun App() {
var isBrowsing by remember { mutableStateOf(true) }
CompositionLocalProvider(LocalElevations provides { edit -> isBrowsing = !edit}) {
if (isBrowsing)
Browser()
} else {
Editor()
}
}
}
@Composable
Editor() {
Button(onClick = { EditorCallback.current(true) }) {
Text(text = "EDIT")
}
}
更安全的方法是控制反转。创建一个包含布尔值的 ViewModel,并将此 ViewModel 插入深度嵌套的 Composable 以及顶级 Composable 中,如下所示:
@Composable
fun App(myViewModel: MyViewModel = viewModel()) {
if (myViewModel.isBrowsing)
Browser() // <-- somewhere inside there is the "Edit" button
} else {
Editor() // <-- somewhere inside there is the "Exit" button
}
}
@Composable
Editor(myViewModel: MyViewModel = viewModel()) {
Button(onClick = { myViewModel.isBrowsing = true }) {
Text(text = "EDIT")
}
}
除了这些建议之外,我认为在 Compose 中传递相当详细的参数确实没问题。最后,这提高了单个可组合项的可测试性。