如何在 Android Jetpack Compose 中的可组合项内启动协程

Qus*_*oon 10 android kotlin android-jetpack-compose

我创建了一个 LazyColumn,它从 viewModel 获取项目,并且一切都工作正常,但我想要的是,当将新项目插入到惰性列时,我希望新项目的背景颜色为绿色 2 秒然后它又变回白色。这就是我为实现这一目标所做的事情,但该项目一直保持绿色:

@Composable
fun SingleItem(item: Item) {
val new = remember {
    mutableStateOf(true)
}
val color: MutableState<Color> = remember {
    if (new.value)
        mutableStateOf(Color(0xFFB9F6CA))
    else
        mutableStateOf(Color(0xFFFDFDFD))
}
Card(
    modifier = Modifier
        .padding(4.dp)
        .fillMaxWidth(),
    shape = RoundedCornerShape(8.dp),
    backgroundColor = color.value
) {
    GlobalScope.launch {
        delay(2000)
        new.value= !new.value
    }
    Column(
        modifier = Modifier
            .fillMaxWidth(),
        horizontalAlignment = Alignment.Start,
        verticalArrangement = Arrangement.SpaceBetween
    ) {
        Text(text = item.name, style = MaterialTheme.typography.h5)
        Text(text = "${item.quantity}", style = MaterialTheme.typography.h6)
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我正在谈论的内容的屏幕截图

Gab*_*tti 13

您可以使用rememberCoroutineScope返回CoroutineScope.
就像是:

// Create a CoroutineScope that follows this composable's lifecycle
val composableScope = rememberCoroutineScope()

composableScope.launch {
    //... your code
}
Run Code Online (Sandbox Code Playgroud)

更多信息请点击这里

  • 现在它给出了一些警告:“启动调用应该发生在 LaunchedEffect 内部,而不是组合内部” (5认同)
  • @brucemax你必须在任何非撰写函数上运行它,比如 onClick (2认同)

chu*_*ckj 3

表达方式,

val color: MutableState<Color> = remember {
    if (new.value)
        mutableStateOf(Color(0xFFB9F6CA))
    else
        mutableStateOf(Color(0xFFFDFDFD))
}
Run Code Online (Sandbox Code Playgroud)

应该只是,

val color = if (new.value) Color(0xFFB9F6CA) else Color(0xFFDFDFD)
Run Code Online (Sandbox Code Playgroud)

lambda toremember仅针对组合调用一次,并且在new更改时不会被视为无效。不需要rememberColor(),因为它足够快,每当new.value发生变化时重复它不会对组合造成重大负担。

另外,正如 Gabriele Mariotti 建议的那样,使用组合范围而不是Global. 在这种情况下,这并不重要,因为它只是可能使引用保持new活动状态的时间比需要的时间长 2 秒,但这是一个非常好的习惯,因为当您使用组合上下文时,协程会在以下情况下自动取消:不再需要组合(例如滚动到屏幕外的行)。

另外,如果颜色不仅仅是用于查看协程效果的占位符,请考虑为此使用动画,因为您可能希望颜色过渡而不是捕捉。