【问题标题】:How to override the text color in TextField in Jetpack Compose using MaterialTheme?如何使用 MaterialTheme 覆盖 Jetpack Compose 中 TextField 中的文本颜色?
【发布时间】:2021-02-09 13:26:34
【问题描述】:

我正在尝试使用来自 Jetpack Compose 的 TextField()。我希望文本颜色为白色。

我发现这是可行的:

ProvideTextStyle(TextStyle(color = Color.White)) {
   TextField(
       ...
   )
}

但是,我想在 Theme 级别覆盖这个,这样我就不需要重复写ProvideTextStyle。我看到MaterialTheme 只接受以下参数:

@Composable
fun MaterialTheme(
    colors: Colors = MaterialTheme.colors,
    typography: Typography = MaterialTheme.typography,
    shapes: Shapes = MaterialTheme.shapes,
    content: @Composable () -> Unit
)

所以我不知道该怎么做。有人可以帮忙吗?

(撰写版本 = 1.0.0-alpha11)

【问题讨论】:

  • 您可以这样定义颜色(颜色是参数 od TextField):colors = TextFieldDefaults.textFieldColors(textColor = YourColor)

标签: android android-layout android-jetpack-compose android-jetpack-compose-text android-compose-textfield


【解决方案1】:

正如Adrian Grygutis在评论中指出的,在1.0.0中,TextField有一个参数colors。您可以通过调用 TextFieldDefaults.textFieldColors(...) 来自定义您的 TextField,并使用您要更改的参数。

TextField(
    ...
    colors: TextFieldColors = TextFieldDefaults.textFieldColors(textColor = Color.White),
) {

至于主题,如果你想避免每次都调用:

ProvideTextStyle(TextStyle(color = Color.White)) {
   TextField(
       ...
   )
}

您可以使用自己的TextFieldColors 集创建一个可组合项,并将其作为参数添加到您的TextField 中。例如,您可以将所有颜色设为白色:

@Composable
fun MyAppTextFieldColors(
    textColor: Color = Color.White,
    disabledTextColor: Color = Color.White,
    backgroundColor: Color = Color.White,
    cursorColor: Color = Color.White,
    errorCursorColor: Color = Color.White,
    ...
) = TextFieldDefaults.textFieldColors(
    textColor = textColor,
    disabledTextColor = disabledTextColor,
    backgroundColor = backgroundColor,
    cursorColor = cursorColor,
    errorCursorColor = errorCursorColor,
    ...
)

为避免在每个TextField 中调用它,您可以为您的应用创建一个自定义MyAppTextField,该应用调用默认TextField,并将您的自定义TextFieldColors 作为默认参数:

@Composable
fun MyAppTextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    ...
    colors: TextFieldColors = DialogoTextFieldColors(),
) {
    TextField(
        value = value,
        onValueChange = onValueChange,
        modifier = modifier,
        ...
        colors = colors,
    )
}

这样,您只需致电MyAppTextField。如果需要,这是覆盖从主题继承的颜色的好方法。

【讨论】:

    【解决方案2】:

    对于1.0.xTextField contentColor 基于LocalContentColor.current。您可以使用CompositionLocalProvider 提供自定义LocalContentColor

    您可以定义一个自定义函数,例如:

    @Composable
    fun ContentColorComponent(
        contentColor: Color = LocalContentColor.current,
        content: @Composable () -> Unit
    ) {
        CompositionLocalProvider(LocalContentColor provides contentColor,
            content = content)
    }
    

    它可以与许多组件一起使用,例如TextField

    ContentColorComponent(contentColor = Color.Blue) {
        TextField(
            value = text,
            onValueChange = { text = it },
            label = { Text("Label") }
        )
    }
    

    【讨论】:

    • 我尝试将它应用于 BasicTextField 但它不起作用,有什么提示吗?为了让它工作,我必须改变这样的风格:textStyle = TextStyle.Default.copy(fontSize = fontSize.sp, color = fontColor)
    【解决方案3】:

    我想在主题级别覆盖它

    在应用的可组合主题中修改MaterialTheme 可组合的内容以包含TextStyle。

    @Composable
    fun MyAppTheme(
        darkTheme: Boolean = isSystemInDarkTheme(),
        content: @Composable() () -> Unit
    ) {
        val colors = if (darkTheme) {
            DarkColorPalette
        } else {
            LightColorPalette
        }
    
        MaterialTheme(
            colors = colors,
            typography = Typography,
            shapes = Shapes,
            content = {
                ProvideTextStyle(
                    value = TextStyle(color = Color.White),
                    content = content
                )
            }
        )
    }
    

    现在您提供的TextStyle 将用于应用主题级别。

    setContent {
        MyAppTheme {
            // app content
        }
    }
    

    【讨论】:

      【解决方案4】:

      您可以使用所需的color 创建自己的TextField 小部件,并在所有地方使用它,

      @Composable
      fun ColoredTextField(value: String, onValueChange: (String) -> Unit){
          ProvideTextStyle(TextStyle(color = Color.White)) {
              TextField(value = value, onValueChange = onValueChange)
          }
      }
      

      现在开始使用ColoredTextField 而不是TextField,并通过更改Widget 中的color,它会应用于所有地方。

      【讨论】:

      • 谢谢!这可能是一个不错的解决方案,但我希望有一种方法可以在主题级别上做到这一点。
      【解决方案5】:

      1.0.0-beta07 中,您可以使用textStyle 属性来覆盖样式和内容颜色。另请参阅Styling TextField

      TextField(
         ...
         textStyle = TextStyle(color = Color.Blue) 
      )
      

      【讨论】:

      • 这只会改变输入到文本字段中的值的颜色,你如何改变标签颜色呢?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      • 2020-03-11
      • 2021-11-14
      • 2023-01-31
      • 2021-10-01
      • 1970-01-01
      • 2022-07-11
      相关资源
      最近更新 更多