Search code examples
androidandroid-jetpack-composeandroid-compose-textfieldandroid-jetpack-compose-material3

Unexpected Text colour alpha in Jetpack Compose Material Theme


I discovered today that MaterialTheme applies an alpha to Text's colour. As you can see from the example attached, when I change the background colour, the text's colour appears to be different because it has a transparency value. I can force set a colour (Text(color = MaterialTheme.colors.onBackground, ....)) and this works correctly but I don't want to have to do this for every single Text.

Why does MaterialTheme do this? How do I override this behaviour?

Compose and Material Compose Material version: 1.2.1

@Preview
@Composable
private fun Preview_Playground() {
    MaterialTheme {
        Box(Modifier.background(Color.Green)) {
            Text("Test", fontWeight = FontWeight.ExtraBold, modifier = Modifier.alpha(1f))
        }
    }
}

enter image description here enter image description here


Solution

  • With M2 (androidx.compose.material) the color of the Text is defined by the color parameter or applying a TextStyle.
    The default value is Color.Unspecified.
    If color = Color.Unspecified and style has no color set, this will be LocalContentColor mixed with LocalContentAlpha.current.

    In the Text.kt you can find:

    val textColor = color.takeOrElse {
            style.color.takeOrElse {
                LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
            }
        }
    

    With M3 (androidx.compose.material3) it doesn't happen since LocalContentColor.current is not mixed:

    val textColor = color.takeOrElse {
        style.color.takeOrElse {
            LocalContentColor.current
        }
    }
    

    If you have to use M2, you can define a custom composable for your Text, or you can change the LocalContentAlpha in the theme for the whole application (not only the Text):

    MaterialTheme(
        colors = colors,
        typography = Typography,
        shapes = Shapes
    ){
    
        CompositionLocalProvider(LocalContentAlpha provides 0.5f) {
            content()
        }
    }