Jetpack Compose TextField 深色模式下的文本颜色
Jetpack Compose TextField text colour in dark mode
我一直在试验 Jetpack compose,我注意到虽然当您切换到深色模式时 Text
的文本颜色会正确更新,但 TextField
或 [= 的文本颜色会正确更新14=] 仍然顽固地变黑。不过,标签和提示的颜色正确。
确定字段的默认文本样式是 MaterialTheme.typography.body1
我更新了我的应用程序主题以包含此解决方法:
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)
但如果那是解决方案,我将不得不为每种排版风格都这样做,而且感觉应该是自动的。那么我做错了什么,或者这是在正式发布之前要解决的问题之一?
这是我的一个实际可组合项(包装在我的主题中):
@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",
)
}
}
1.0.0
TextField
的文本颜色在深色模式下应该可以正常工作。
无论如何,textColor 当前基于:
textColor: Color = LocalContentColor.current.copy(LocalContentAlpha.current)
您可以避免使用类似以下内容更改每个排版样式:
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colors.secondary) {
TextField(
value = text,
onValueChange = { text = it },
label = { Text("Label") }
)
}
为了自定义 OutlinedTextField 组件上的每种颜色,我一直在做的是使用 "colors" 参数 以及 "TextFieldDefaults.outlinedTextFieldColors()" 方法。
下面是一个例子:
OutlinedTextField(
value = text,
onValueChange = { text = it },
colors = TextFieldDefaults.outlinedTextFieldColors(
unfocusedLabelColor = MaterialTheme.colors.primary
)
)
在“outlinedTextFieldColors”上,基本上可以定义TextField状态所需的所有颜色,如下所示:
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)
)
我对这个实现的深色和浅色主题没有任何问题。
尝试用 Surface 包装它/在使用 UsernameField
的可组合项中应用 Surface。简而言之,您没有适当的背景,文本可以采用适当的颜色配置来形成对比。
有可能的行为和修复的简短示例:
@Preview
@Composable
fun DarkModeTest() {
MaterialTheme(darkColors()) {
Column {
Surface {
OutlinedTextField(value = "good", onValueChange = {})
}
OutlinedTextField(value = "bad", onValueChange = {})
}
}
}
通过查看文档:
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.
我一直在试验 Jetpack compose,我注意到虽然当您切换到深色模式时 Text
的文本颜色会正确更新,但 TextField
或 [= 的文本颜色会正确更新14=] 仍然顽固地变黑。不过,标签和提示的颜色正确。
确定字段的默认文本样式是 MaterialTheme.typography.body1
我更新了我的应用程序主题以包含此解决方法:
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)
但如果那是解决方案,我将不得不为每种排版风格都这样做,而且感觉应该是自动的。那么我做错了什么,或者这是在正式发布之前要解决的问题之一?
这是我的一个实际可组合项(包装在我的主题中):
@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",
)
}
}
1.0.0
TextField
的文本颜色在深色模式下应该可以正常工作。
无论如何,textColor 当前基于:
textColor: Color = LocalContentColor.current.copy(LocalContentAlpha.current)
您可以避免使用类似以下内容更改每个排版样式:
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colors.secondary) {
TextField(
value = text,
onValueChange = { text = it },
label = { Text("Label") }
)
}
为了自定义 OutlinedTextField 组件上的每种颜色,我一直在做的是使用 "colors" 参数 以及 "TextFieldDefaults.outlinedTextFieldColors()" 方法。
下面是一个例子:
OutlinedTextField(
value = text,
onValueChange = { text = it },
colors = TextFieldDefaults.outlinedTextFieldColors(
unfocusedLabelColor = MaterialTheme.colors.primary
)
)
在“outlinedTextFieldColors”上,基本上可以定义TextField状态所需的所有颜色,如下所示:
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)
)
我对这个实现的深色和浅色主题没有任何问题。
尝试用 Surface 包装它/在使用 UsernameField
的可组合项中应用 Surface。简而言之,您没有适当的背景,文本可以采用适当的颜色配置来形成对比。
有可能的行为和修复的简短示例:
@Preview
@Composable
fun DarkModeTest() {
MaterialTheme(darkColors()) {
Column {
Surface {
OutlinedTextField(value = "good", onValueChange = {})
}
OutlinedTextField(value = "bad", onValueChange = {})
}
}
}
通过查看文档:
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.