Reputation: 13867
I've been experimenting with Jetpack compose and I've noticed that although the text colour updates correctly for Text
when you switch to dark mode, the text colour for TextField
or OutlinedTextField
remains stubbornly black. The labels and hint are correctly coloured though.
Having determined that the default text style for the fields is MaterialTheme.typography.body1
I have updated my app theme to include this workaround:
val typography = if (darkTheme) {
//TODO: Hack to show text field text in dark mode
MaterialTheme.typography.copy(body1 = MaterialTheme.typography.body1.copy(color = Color.White))
} else {
MaterialTheme.typography
}
MaterialTheme(colors = colors, content = content, typography = typography)
But if that is the solution I would have to do that for every typography style and it feels like something that should be automatic. So am I doing something wrong, or is this one of those kinks that will be ironed out before it is officially released?
Here is one of my actual Composables (wrapped in my Theme):
@Composable
fun UsernameField(
value: String,
isError: Boolean,
onValueChange: (String) -> Unit,
) {
Column {
OutlinedTextField(
value = value,
onValueChange = onValueChange,
modifier = Modifier.fillMaxWidth(),
label = { Text("Username") },
isError = isError,
trailingIcon = {
ClearIcon(
visible = value.isNotEmpty(),
onClick = { onValueChange("") }
)
}
)
Text(
if (isError) "Minimum 6 characters" else "",
style = MaterialTheme.typography.caption,
color = MaterialTheme.colors.error,
modifier = Modifier.padding(top = 4.dp)
)
}
}
@Composable
fun ClearIcon(visible: Boolean, onClick: () -> Unit) {
if (visible) IconButton(onClick = onClick) {
Icon(
imageVector = Icons.Filled.Cancel,
contentDescription = "Clear username",
)
}
}
Upvotes: 11
Views: 10976
Reputation: 14352
Try the below solution
OutlinedTextField(
value = state.searchQuery,
onValueChange = onValueChange,
modifier = Modifier
.padding(48.dp)
.fillMaxWidth(),
placeholder = {
Text(
text = "Search...",
color = Color.White,
fontSize = MaterialTheme.typography.titleSmall.fontSize,
fontWeight = FontWeight.Bold
)
},
colors = TextFieldDefaults.outlinedTextFieldColors(
unfocusedLabelColor = MaterialTheme.colorScheme.inversePrimary,
textColor = Color.White
),
maxLines = 1,
singleLine = true
)
Upvotes: -1
Reputation: 363597
With 1.0.0
the text color of TextField
should work without issue in dark mode.
In any case the textColor is currently based on:
textColor: Color = LocalContentColor.current.copy(LocalContentAlpha.current)
You can avoid to change every typography styles using something like:
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colors.secondary) {
TextField(
value = text,
onValueChange = { text = it },
label = { Text("Label") }
)
}
Upvotes: 6
Reputation: 374
Try to wrap it with Surface / apply Surface in composable which uses UsernameField
. To put it simply, you don't have proper background on which text could take proper color configuration to contrast it.
There is short example of possible behaviour and fix:
@Preview
@Composable
fun DarkModeTest() {
MaterialTheme(darkColors()) {
Column {
Surface {
OutlinedTextField(value = "good", onValueChange = {})
}
OutlinedTextField(value = "bad", onValueChange = {})
}
}
}
By looking into docs:
The Surface is responsible for:
...
Content color: Surface uses contentColor to specify a preferred color for the content of this surface - this is used by the Text and Icon components as a default color.
Upvotes: 17
Reputation: 888
What I have been doing to customize every color on my OutlinedTextField components, is to use the "colors" argument along with the "TextFieldDefaults.outlinedTextFieldColors()" method.
Below is an example:
OutlinedTextField(
value = text,
onValueChange = { text = it },
colors = TextFieldDefaults.outlinedTextFieldColors(
unfocusedLabelColor = MaterialTheme.colors.primary
)
)
On "outlinedTextFieldColors", you can define basically all of the colors you need in terms of a TextField state, as shown as below:
Creates a TextFieldColors that represents the default input text, background and content (including label, placeholder, leading and trailing icons) colors used in an OutlinedTextField.
@Composable
fun outlinedTextFieldColors(
textColor: Color = LocalContentColor.current.copy(LocalContentAlpha.current),
disabledTextColor: Color = textColor.copy(ContentAlpha.disabled),
backgroundColor: Color = Color.Transparent,
cursorColor: Color = MaterialTheme.colors.primary,
errorCursorColor: Color = MaterialTheme.colors.error,
focusedBorderColor: Color =
MaterialTheme.colors.primary.copy(alpha = ContentAlpha.high),
unfocusedBorderColor: Color =
MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled),
disabledBorderColor: Color = unfocusedBorderColor.copy(alpha = ContentAlpha.disabled),
errorBorderColor: Color = MaterialTheme.colors.error,
leadingIconColor: Color =
MaterialTheme.colors.onSurface.copy(alpha = IconOpacity),
disabledLeadingIconColor: Color = leadingIconColor.copy(alpha = ContentAlpha.disabled),
errorLeadingIconColor: Color = leadingIconColor,
trailingIconColor: Color =
MaterialTheme.colors.onSurface.copy(alpha = IconOpacity),
disabledTrailingIconColor: Color = trailingIconColor.copy(alpha = ContentAlpha.disabled),
errorTrailingIconColor: Color = MaterialTheme.colors.error,
focusedLabelColor: Color =
MaterialTheme.colors.primary.copy(alpha = ContentAlpha.high),
unfocusedLabelColor: Color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),
disabledLabelColor: Color = unfocusedLabelColor.copy(ContentAlpha.disabled),
errorLabelColor: Color = MaterialTheme.colors.error,
placeholderColor: Color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),
disabledPlaceholderColor: Color = placeholderColor.copy(ContentAlpha.disabled)
)
I haven't been having any issue with Dark and Light themes with this implementation.
Upvotes: 3