Reputation: 319
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
Upvotes: 10
Views: 8737
Reputation: 29545
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.
Upvotes: 3
Reputation: 363955
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 info here.
Upvotes: 15