我完全搞不懂作曲的概念。我有一个代码
@Composable
fun HomeScreen(viewModel: HomeViewModel = getViewModel()) {
Scaffold {
val isTimeEnable by viewModel.isTimerEnable.observeAsState()
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center,
modifier = Modifier
.fillMaxSize()
.background(Color.Black),
) {
Switch(
checked = isTimeEnable ?: false,
onCheckedChange = {
viewModel.setTimerEnable(it)
},
)
Clock(viewModel.timeSelected.value!!) {
viewModel.setTime(it)
}
}
}
}
@Composable
fun Clock(date: Long, selectTime: (date: Date) -> Unit) {
NumberClock(Date(date)) {
val time = SimpleDateFormat("HH:mm", Locale.ROOT).format(it)
Timber.d("Selected time: time")
selectTime(it)
}
}
为什么Clock
小工具在我点击开关时会重组。如果我从Clock
小工具中删除selectTime(it)
行,回调重组不会发生。1.0.2
2条答案
按热度按时间z31licg01#
这是因为在compose中,你每次都在创建一个新的
selectTime
lambda,所以重新组合是必要的。如果你传递setTime
函数作为引用,compose会知道它是同一个函数,所以不需要重新组合:或者,如果你有更复杂的处理程序,你可以
remember
它。双括号({{ }}
)在这里很关键,因为你需要记住lambda。我知道这看起来有点奇怪,你可以使用
rememberLambda
,这将使你的代码更可读:请注意,您需要将所有可能更改的值作为键传递,因此
remember
将根据需要重新计算。一般来说,重新组合并不是一件坏事。当然,如果你可以减少它,你应该这样做,但是你的代码应该工作正常,即使它被重新组合了很多次。例如,你不应该在composable里做大量的计算来完成这件事,而是使用side effects。
因此,如果重新组合
Clock
会导致奇怪的UI效果,则可能是您的NumberClock
有问题,无法在重新组合后继续存在。如果是这样,请将NumberClock
代码添加到您的问题中,以获得如何改进它的建议。gxwragnw2#
这是预期的行为。当用户切换开关时,您显然是在修改视图模型中的
isTimeEnabled
字段(通过调用vm.setTimeenabled)。现在,很明显,视图模型中的isTimeEnabled
是一个LiveData
示例,您通过在其上调用observeAsState
从Composable中引用该示例。因此,当您修改开关的onValueChange中的值时,您实际上是在修改Composable所依赖的状态。