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

how to launch a coroutine inside a composable in Android Jetpack Compose

我创建了一个从 viewModel 中获取项目的 LazyColumn,并且一切正常,但是 我想要的是当一个新项目插入到惰性列时我想要背景颜色新项目的绿色 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)
    }
}

Here is a Screen shot of what I am talking about

您可以使用 rememberCoroutineScope 函数 returns a CoroutineScope
类似于:

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

composableScope.launch {
    //... your code
}

更多信息here

表达式,

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

应该就是,

val color = if (new.value) Color(0xFFB9F6CA) else Color(0xFFDFDFD)

remember 的 lambda 只为组合调用一次,并且在 new 更改时不会被视为无效。不需要 remember 一个 Color() 值,因为它足够快,只要 new.value 发生变化就重复它不会对合成造成重大负担。

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

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