目前将我的应用程序转换为 Jetpack compose,在某些情况下我面临着一些调整当前调色板的问题。
我的 xml 文件中有一些
TextInputLayout
,它们继承了主题上次要颜色的突出显示文本颜色。
<style name="Theme.MyApp" parent="Theme.MaterialComponents.Light.NoActionBar">
...
<item name="colorPrimary">@color/blue</item>
<item name="colorPrimaryVariant">@color/blue</item>
<item name="colorSecondary">@color/red</item>
<item name="colorSecondaryVariant">@color/red</item>
...
</style>
问题是我的撰写中的
TextField
继承了 MaterialTheme
上的主颜色的突出显示文本颜色。
MaterialTheme(
colors = Colors(
primary = Color.Blue,
...
secondary = Color.Red,
...
),
content = content,
typography = MaterialTheme.typography,
shapes = MaterialTheme.shapes,
) {
TextField(...)
}
我覆盖了
colors
上的 TextField
参数,但似乎没有一个影响这种颜色。
是否有一种方法可以在不更改
colors
上的 MaterialTheme
的情况下覆盖构图上的突出显示颜色?我想避免这种情况,因为它可能会在使用相同主题的其他屏幕上引起问题。
LocalTextSelectionColors.current
提供。
TextSelectionColors
:
val customTextSelectionColors = TextSelectionColors(
handleColor = Red,
backgroundColor = Red.copy(alpha = 0.4f)
)
CompositionLocalProvider(LocalTextSelectionColors provides customTextSelectionColors) {
TextField(
value = text,
onValueChange = { text = it },
colors = TextFieldDefaults.textFieldColors(cursorColor = Red)
)
}
如果您还想更改光标颜色,请添加
colors = TextFieldDefaults.textFieldColors(cursorColor = Red)
。
两者:手柄和选择背景都可以在组合本地提供商的帮助下更改。
颜色定义示例(首选
colorTheme
而不是直接使用颜色定义):
val Ecstasy = Color(0xFFF58220)
选择颜色定义:
val selectionColors = TextSelectionColors(
backgroundColor = Ecstasy.copy(alpha = 0.37f),
handleColor = Ecstasy
)
它可以与
BasicTextField
(在 Compose 1.7.0-beta 中重命名的 BasicTextField2
)一起使用,但我认为没有理由它不能与 TextField
或任何 MaterialTextField
-s 一起使用。
CompositionLocalProvider(
LocalTextSelectionColors provides colors.textSelectionColors
) {
BasicTextField(...)
}
由于每次使用文本字段时都使用组合提供程序可能会很烦人,因此您始终可以考虑实现自己的可组合项。
这正是文档的建议:
使用现成的构建块编写 Jetpack Compose 应用程序,并扩展基础以构建您自己的设计系统组件。
如果可组合功能未按预期工作,始终可以创建一个符合要求的组合。
然后就可以使用设计系统级可组合项,而不是直接调用
BasicTextField
。
最近我创建了一个符合要求的文本字段:
结果是:
实现方式很简单,如下所示:
fun TextField(
modifier: Modifier = Modifier,
state: TextFieldUiState,
onValueChange: Consumer<String>,
label: String? = null,
keyboardActions: KeyboardActions = KeyboardActions(),
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
maxLines: Int = Int.MAX_VALUE,
singleLine: Boolean = false,
visualTransformation: VisualTransformation = VisualTransformation.None,
colors: TextFieldColors = TextFieldDefaults.colors()
) {
fun TextField(
modifier: Modifier = Modifier,
state: TextFieldUiState,
onValueChange: Consumer<String>,
label: String? = null,
keyboardActions: KeyboardActions = KeyboardActions(),
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
maxLines: Int = Int.MAX_VALUE,
singleLine: Boolean = false,
visualTransformation: VisualTransformation = VisualTransformation.None,
colors: TextFieldColors = TextFieldDefaults.colors()
) {
val textStyle =
TextStyle(color = colors.focusedTextColor)
val borderWidth = when (state.isError()) {
true -> 1.dp
false -> 0.dp
}
val borderColor = when (state.isError()) {
true -> colors.errorIndicatorColor
false -> Transparent
}
CompositionLocalProvider(
LocalTextSelectionColors provides colors.textSelectionColors
) {
BasicTextField(
value = state.value,
onValueChange = onValueChange,
modifier = modifier.border(
width = borderWidth,
color = borderColor
),
enabled = state.enabled,
keyboardActions = keyboardActions,
keyboardOptions = keyboardOptions,
singleLine = singleLine,
maxLines = maxLines,
textStyle = textStyle,
cursorBrush = SolidColor(colors.cursorColor),
visualTransformation = visualTransformation,
decorationBox = @Composable { innerTextField ->
DecorationBox(
value = state.value,
visualTransformation = visualTransformation,
innerTextField = innerTextField,
label = label?.let { { Text(text = it) } },
shape = RectangleShape,
singleLine = singleLine,
enabled = state.enabled,
interactionSource = remember { MutableInteractionSource() },
colors = colors
)
}
)
}
}
}
大部分主题是通过
TextFieldDefaults.colors()
的自定义实现完成的。