Hey, is there a know bug where the `onX` colors ha...
# compose
u
Hey, is there a know bug where the
onX
colors have some sort of weird tint when used implcitly? I have a parent surface whose color is set to
MaterialTheme.colors.primary
, and then just a simple
Text
where its inferred text color should be
onPrimary
and it some off-white, when it should be pure white
If I have another
Text
on top of it which color explicitly set to
onPrimary
then it is white as it should. compose version 1.2.1
Copy code
Snippet in the thread
u
Copy code
@Composable
fun HeaderRow(item: Header) {
    Surface(
        color = MaterialTheme.colors.primary,
        modifier = Modifier
            .fillMaxWidth()
            .wrapContentHeight()
    ) {
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .wrapContentHeight()
                .padding(
                    start = DefaultPadding,
                    end = DefaultPadding,
                    top = 4.dp,
                    bottom = SectionPadding / 2,
                ),
            horizontalAlignment = Alignment.Start
        ) {
            val greeting = "Dobrý večer"

            Box {
                Text(
                    modifier = Modifier
                        .wrapContentSize()
                        .padding(bottom = 4.dp),
                    text = greeting,
                    style = MaterialTheme.typography.h2,
                )
                Text(
                    modifier = Modifier
                        .wrapContentSize()
                        .padding(bottom = 4.dp, start = 4.dp),
                    text = greeting,
                    style = MaterialTheme.typography.h2,
                    color = MaterialTheme.colors.onPrimary <--------------------
                )
            }
            Text(
                modifier = Modifier.wrapContentSize(),
                text = item.tariffName,
                style = MaterialTheme.typography.caption,
            )
        }
    }
}
There is some sort of alpha added to stuff, what am I doing wrong? its not just this case
m
Generally, the only thing that would affect the alpha value would be
LocalContentAlpha
and
LocalContentColor
. You might want to see what the values are for those during this composition. The particular content alpha is generally based on luminance of the LocalContentColor.
u
what... youre right why would anyone think its a good idea to have nondeterministic designs??
I could spot right away that white is not white, and it didnt look better either
m
I did a basic test like this:
Copy code
MaterialTheme {
        // A surface container using the 'background' color from the theme
        Surface(
            modifier = Modifier.fillMaxSize(),
            color = MaterialTheme.colors.primary
        ) {

            Column {
                Text(text = "Hello Android!", color = MaterialTheme.colors.onPrimary, style = MaterialTheme.typography.h2,)
                CompositionLocalProvider(
                    LocalContentAlpha provides 0.5f
                ) {
                    Text(text = "Hello Android2!", color = MaterialTheme.colors.onPrimary, style = MaterialTheme.typography.caption,)
                }
            }
        }
    }
message has been deleted
FYI: If i explicitly increase the font size of the second element by making a copy of the caption with 36.dp instead, the two elements look more similar
message has been deleted
and the LocalContentAlpha had no effect on the second text element when i removed that. I just get the feeling that it's due to the small font size and the edge blending / anti aliasing that's going on. Edit: My example above have explicit colors, so they looked the same
u
well in my case its for sure alpha value, not antialiasing, optical illusion or what not
any way to turn this arguments generating feature off?
m
It's part of compose. The default color for Text is
Color.Unspecified
. When that happens, the text engine will go through a series of things. It will look at your typography first to see if it has a color (which would generally also be
Color.Unspecified
. If that happens it will fall back to the LocalContentColor. And as we've seen when you create a surface with a color, it defaults the content color to this:
Copy code
contentColor: Color = contentColorFor(color),
which essentially uses LocalContentColor (in this case onPrimary because your surface is using primary). And that's getting an alpha applied to it implicitly based on the luminance of the color. In ContentAlpha.kt:
Copy code
@Composable
    private fun contentAlpha(
        /*@FloatRange(from = 0.0, to = 1.0)*/
        highContrastAlpha: Float,
        /*@FloatRange(from = 0.0, to = 1.0)*/
        lowContrastAlpha: Float
    ): Float {
        val contentColor = LocalContentColor.current
        val lightTheme = MaterialTheme.colors.isLight
        return if (lightTheme) {
            if (contentColor.luminance() > 0.5) highContrastAlpha else lowContrastAlpha
        } else {
            if (contentColor.luminance() < 0.5) highContrastAlpha else lowContrastAlpha
        }
    }
the way to combat this is really just to either deliberately override the LocalContentColor yourself, or set the color on the element itself directly to onPrimary.
You can do this, but i'm not really sure how you'd disable the behavior:
Copy code
color = LocalContentColor.current.copy(alpha=1.0f)