Animating Colors the Wrong Way Link to heading

If you animate an integer color from white to black, this is the result:

Column {
    var targetColor by remember { mutableIntStateOf(0xFFFFFF) }

    LaunchedEffect(Unit) {
        targetColor = 0x000000
    }

    val animatedColorValue by animateIntAsState(targetColor, tween(2000))

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(Color(0XFF000000 or animatedColorValue.toLong()))
    )
}

Animating Colors the Right Way Link to heading

Most developers know that color integers are made up of four parts: Alpha, Red, Green, and Blue. To get a smooth color animation, we just need to animate each of these values independently:

Column {
    var targetColor by remember { mutableStateOf(Color(0xFFFFFFFF)) }

    LaunchedEffect(Unit) {
        targetColor = Color(0xFF000000)
    }

    val r by animateFloatAsState(targetColor.red, tween(2000))
    val g by animateFloatAsState(targetColor.green, tween(2000))
    val b by animateFloatAsState(targetColor.blue, tween(2000))

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(Color(r, g, b))
    )
}

Animating Colors in Jetpack Compose Link to heading

Jetpack Compose provides several APIs to us for animating color. We can use them to improve our code:

Column {
    var targetColor by remember { mutableStateOf(Color(0xFFFFFFFF)) }

    LaunchedEffect(Unit) {
        targetColor = Color(0xFF000000)
    }

    val animatedColor by animateColorAsState(targetColor, tween(2000))

    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(animatedColor)
    )
}