I create a project with the wizard Empty Compose Activity of Android Studio. I use Text("Hello") to display a text.
I know the font size of the text is 16.sp by looking source code, but how can I know which color is displayed of the text?
BTW, I look at the source code , the color of font is specified as Color.Unspecified, I don't know what color will be displayed for Color.Unspecified.
Source Code
// Set of Material typography styles to start with
val Typography = Typography(
body1 = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp
)
...
)
class TextStyle
@OptIn(ExperimentalTextApi::class)
internal constructor(
...
) {
...
@OptIn(ExperimentalTextApi::class)
constructor(
color: Color = Color.Unspecified,
fontSize: TextUnit = TextUnit.Unspecified,
...
}
val Unspecified = Color(0f, 0f, 0f, 0f, ColorSpaces.Unspecified)
ACCEPTED]
The color in the Text is defined by the color parameter or applying a TextStyle. The default value is
Color.Unspecified
[1].
If color = Color.Unspecified and style has no color set, this will be
LocalContentColor
[2] which provides a default
Color.Black
[3] color if not specified.
If we look at the source code of Text composable, we can find,
val textColor = color.takeOrElse {
style.color.takeOrElse {
LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
}
}
color is the argument passed to the Text composable, which defaults to Color.Unspecified if no color is passed.We see a method takeOrElse is used.
takeOrElse definition
inline fun Color.takeOrElse(block: () -> Color): Color = if (isSpecified) this else block()
Color.isSpecified definition
inline val Color.isSpecified: Boolean get() = value != Color.Unspecified.value
In other words, we can read this code as set textColor as the color if it is not equal to Color.Unspecified, else use the value in the given lambda.
Since we already know the color is Color.Unspecified if no color is specified (from above point 1), the value in the lambda will be used.
The lambda checks if there is a color in the style TextStyle provided (either by user or by default value LocalTextStyle.current). If there is one, it will be used. Else the value of the below will be used.
LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
LocalContentColor, LocalContentAlpha and LocalTextStyle are provided using CompositionLocalProvider.
LocalTextStyle.current ? so I can know such as font size, font color, and so on. - HelloCW
LocalTextStyle, LocalContentColor, etc. vary according to their composable. If called from Button you might get a different value than when called from Scaffold body. The easiest way to determine the value is to either create a variable and use a debugger or log the values. - Abhimanyu
As the other answers explain which color is interpreted when color is Color.Unspecified (which is LocalContentColor.current), I will answer why there is a Color.Unspecified instead of Color.Transparent
Because Color is an inline class, this represents an unset value without having to
box
[1] the Color object. It will be treated as Transparent when drawn. A Color object can be compared with Color.Unspecified for equality check, or the property isUnspecified of the object can be used to check for the unset value (or Color#isSpecified for any color that isn't Color.Unspecified).
This approach is used with Offset.Unspecified, Size.Unspecified and other classes that have an equivalent 'Unspecified' field for equality checks.
I don't know what color will be displayed for Color.Unspecified.
If you need to get the color dynamically at runtime, for example if you dynamically set colors and need them to change based on their current color you can use
Text("Hello World",
onTextLayout = {
it.layoutInput.style.color
}
)
Which will return
And if you assign a Color
Text("Hello World",
color = Color.Red,
onTextLayout = {
it.layoutInput.style.color
}
)
[1] https://discuss.kotlinlang.org/t/autoboxing-done-right-how-by-using-to-functions/8927
Color.BlackforLocalContentColor- HelloCWColor.Blackand user can overwrite it. - HelloCW