每秒创建一个新的可组合元素

Create a new composable element every second

提问人:Marco 提问时间:10/22/2023 更新时间:10/22/2023 访问量:28

问:

我正在尝试一个每秒射出一个球的循环。 球本身有一个协程,可以动画化它的偏移量X。 下面我有一个带按钮的行,它激活了一个带有 while 循环的协程,可以发射球。我这样做的方式显然行不通:一个球被击中,仅此而已。 我怎样才能触发一个循环,让它不断射球,并且不干扰球本身的协程? 作为作曲的新手,我仍然无法弄清楚该怎么做。有人可以帮忙吗?

这是带有 Button 的 Row、coroutinge、无限 while 循环和 isLoading 更改时创建的 Ball。

val coroutineScope = rememberCoroutineScope()
var isLoading by remember { mutableStateOf(false) }

Row(
            horizontalArrangement = Arrangement.End,
            verticalAlignment = Alignment.Top,
            modifier = Modifier
                .width(noteSize * scoreLength)
                .fillMaxHeight()
        ) {
            Button(
                colors = ButtonDefaults.buttonColors(containerColor = Color.Red),
                onClick = {                    
                    coroutineScope.launch {
                       while (true){
                         isLoading = true
                         delay(1000)
                         isLoading = false
                       }                       
                    }
                }) { 
                Text(text = "shoot")
            }

            if (isLoading) Ball(noteSize, noteSize / 2 + (noteSize / 2) * 8, 8, w)               
          }
}

这是当它被击中时向左移动的注意。作为可组合项的 Note 实际上是一个 OutlinedButton。

@Composable
fun Ball(
    noteSize: Dp,
    verticalOffSet: Dp,
    target: Float,
) {
    val coroutineScope = rememberCoroutineScope()
    val offsetX = remember { Animatable(350f) }
    val v = verticalOffSet.dpToPx().toInt()

    OutlinedButton(
        colors = ButtonDefaults.buttonColors(containerColor = Color.Red),
        onClick = { },
        modifier = Modifier
            .offset {
                IntOffset(
                    offsetX.value.toInt(),
                    v
                )
            }
            .size(noteSize),
        shape = CircleShape
    ) { }
    coroutineScope.launch {
        offsetX.animateTo(
            targetValue = -target,
            animationSpec = tween(durationMillis = 3000, easing = LinearEasing))
    }
}
while-loop kotlin 协程 延迟

评论

0赞 Glenn Sandoval 10/22/2023
这句话不会创造新的球。它显示或隐藏该球。再加一个,你就会清楚地看到它。if (isLoading)delay(1000)isLoading = false
0赞 Marco 10/23/2023
我的天啊!就是这么简单!谢谢!!现在,既然这可行,我问题的第二部分“......不会干扰球本身的协程“,这意味着:一旦击球,球应该继续运行 3 秒,正如您在球的动画中看到的那样,但它只持续 1 秒,直到再次被触发。如何使球的协程独立于按钮的协程?
0赞 Glenn Sandoval 10/24/2023
它是独立的,但你有点困惑。corotuine 所做的只是显示和隐藏球。当球被隐藏时,它会从UI树中取出,所以当它“再次显示”时,它实际上是一个全新的球,而不是同一个球。您需要将每个球信息存储在列表中,并为列表中的每个项目创建一个球。
0赞 Marco 10/25/2023
我确实很困惑。至少自从我从舒适的 Java/XML 转向 Kotlin/Compose 以来。我今天得出了与你相同的结论,但没有时间实施。至少我没有那么不高兴。谢谢!

答: 暂无答案