我正在学习作曲,作为一个练习,我试图显示一个倒计时器列表。一个按钮将添加一个新的计时器到列表中,然后对于该列表中的每个计时器,lazycolumn将显示一行,其中包含显示倒计时时间的文本和开始倒计时的按钮。
在这里,我添加了三个计时器到列表中,它们都显示得很好:
然后,当我开始倒计时时,所有其他行都会更新,即使它们没有被更改:
我的视图模型:
data class MyClass(val text: String, val isClickable: Boolean)
class VM : ViewModel() {
val myList = mutableStateListOf<MyClass>()
fun addTimer() {
myList.add(myList.size, MyClass("0", true))
}
fun changeText(index: Int, tempo: String) {
myList[index] = myList[index].copy(text = tempo)
}
fun changeIsClickable(index: Int, click: Boolean) {
myList[index] = myList[index].copy(isClickable = click)
}
}
我的可组合屏幕:
val viewModel: VM by viewModels()
(...)
@Composable
fun MainScreen(viewModel: VM) {
val scope = CoroutineScope(Dispatchers.Main)
Column(verticalArrangement = Arrangement.spacedBy(15.dp)) {
Row() {
Button(onClick = { viewModel.addTimer() }
) {
Text(text = "Add Timer")
}
}
LazyColumn {
itemsIndexed(viewModel.myList) { index, list ->
Row(modifier = Modifier.border(8.dp, randomColor())) {
Text(
text = list.text, modifier = Modifier
.padding(20.dp)
)
Button(
enabled = list.isClickable,
onClick = {
viewModel.changeIsClickable(index, false)
var currTime = Calendar.getInstance().timeInMillis
val endTime =
currTime + (7000L..20000L).random() //random between 7 and 20
scope.launch {
while (endTime > currTime) {
delay(100)
val timeTemporary =
((endTime - currTime) / 1000).toString() + "\n" + "Secs"
viewModel.changeText(index, timeTemporary)
currTime = Calendar.getInstance().timeInMillis
}
viewModel.changeText(index, "Done")
viewModel.changeIsClickable(index, true)
}
}) {
Text(text = "Start")
}
}
}
}
}
}
我尝试了很多建议,比如this one和this one(因此使用彩色边框来检查重组),但我无法使未更改的行不更新。我错过了什么?我怎样才能阻止lazycolumn在不应该更新的时候进行更新?
1条答案
按热度按时间pu3pd22g1#
将项目添加到单独的组合项中。每个可组合函数是否可跳过取决于可组合函数的参数。在本例中,您将索引和项作为参数。当计时器不运行时,这两个参数都不会改变,并且因为这两个参数都不会改变,所以在重组过程中将跳过可组合对象。