简体   繁体   中英

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

I created a LazyColumn that is getting the items from the viewModel and every thing is working perfectly, But What I want is when a new Item is inserted to the lazy column I want the the background color of the new Item to be green for 2 seconds and then it turns back to white . And here is what I did to achieve that but the Item keeps being green:

@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

You can use the rememberCoroutineScope function that returns a CoroutineScope .
Something like:

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

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

More infohere .

The expression,

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

should just be,

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

The lambda to remember is only ever called once for the composition and is not considered invalid when new changes. There is no need to remember a Color() value as it is fast enough that repeating it whenever new.value is changes is not going to be a significant burden for composition.

Also, as Gabriele Mariotti suggested, use the composition scope instead of Global . In this case, it doesn't matter much as it just potentially keeps the reference to new alive for 2 seconds longer than needed but it is a very good habit to get into as, when you use the composition context the coroutine is cancelled automatically when the composition is no longer needed (such as the row scrolling off screen).

Also, if the color is not just a placeholder for seeing the effect of a coroutine, consider using animations for this as you would probably want the color to transition instead of snap.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM