本文介绍了为什么在回调中调用ViewModel时会发生重组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我完全搞不懂作曲这个概念。我有一个代码
@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
推荐答案
这是因为在组合方面,您每次都会创建一个新的selectTime
lambda,因此需要重新组合。如果将setTime
函数作为引用传递,Compose将知道它是同一个函数,因此不需要重新组合:
Clock(viewModel.timeSelected.value!!, viewModel::setTime)
或者,如果您有更复杂的处理程序,您可以remember
:
Clock(
date = viewModel.timeSelected.value!!,
selectTime = remember(viewModel) {
{
viewModel.setTimerEnable(it)
}
}
)
请注意,您需要将可能更改的所有值作为键传递,因此remember
将按需重新计算。
总的来说,重组并不是一件坏事。当然,如果您可以减少它,您应该这样做,但您的代码应该可以很好地工作,即使它被多次重新组合。例如,您不应该在Composable中进行繁重的计算,而应该使用side effects。
因此,如果重新组合Clock
导致奇怪的UI效果,可能是NumberClock
有问题,无法在重新组合后存活。如果是,请将NumberClock
代码添加到您的问题中,以获取有关如何改进它的建议。
这篇关于为什么在回调中调用ViewModel时会发生重组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!