I'm a frog dragon
I'm a frog dragon

Reputation: 8815

How to override the text color in TextField in Jetpack Compose using MaterialTheme?

I'm trying to use TextField() from Jetpack Compose. I want the text color to be white.

I found this to be working:

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

However, I want to override this in the Theme level, so that I don't need to repeatedly write ProvideTextStyle. I saw that MaterialTheme only accepts the following params:

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

So I'm not sure how to do it. Can someone help?

(compose version = 1.0.0-alpha11)

Upvotes: 31

Views: 40728

Answers (6)

Gabriele Mariotti
Gabriele Mariotti

Reputation: 363845

The M2 TextField contentColor is based on LocalContentColor.current. You can use the CompositionLocalProvider to provide a custom LocalContentColor.

You can define a custom function like:

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

It can be used with many components, for example the TextField:

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

enter image description here

Upvotes: 15

Henrique Prandi
Henrique Prandi

Reputation: 41

Configure your application's MaterialTheme with your own Color object configuration, setting the content color parameters (onPrimary, onSecondary and so on).

MaterialTheme(
    colors = Colors(
        primary = Color.Black,
        secondary = Color.Black,
        background = Color.Black,
        onPrimary = Color.Red,
        onSecondary = Color.Red,
        onBackground = Color.Red
    )
)

Note: for the font colors to take effect, you must set the main colors (primary, secondary and so on). This is due to the logic defined in androidx.compose.material.Colors::contentColorFor.

Upvotes: 0

Arthur Bertemes
Arthur Bertemes

Reputation: 1286

As Adrian Grygutis pointed out on the comment, in 1.0.0, TextField has a parameter colors. You could customize your TextField by calling TextFieldDefaults.textFieldColors(...) with the parameter you want to change.

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

As for theming, and if you want to avoid calling every time:

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

You could create a composable with your own set of TextFieldColors and add it as a parameter in your TextField. You could for instance, have all colors as white:

@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,
    ...
)

To avoid calling this in every TextField, you can then create a custom MyAppTextField for your app that calls the default TextField with your custom TextFieldColors as a default parameter:

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

That way, you would only need to call MyAppTextField. It's a good way to override colours inherited from the theme if needed.

Upvotes: 27

Om Kumar
Om Kumar

Reputation: 1664

I want to override this in the Theme level

Modify the content of MaterialTheme composable in your app's theme composable to include 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
            )
        }
    )
}

Now your provided TextStyle will be used at App theme level.

setContent {
    MyAppTheme {
        // app content
    }
}

Upvotes: 17

yannickpulver
yannickpulver

Reputation: 2275

In 1.0.0-beta07 you are able to use the textStyle property to override the style and therefore the content color. Also, see Styling TextField.

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

Upvotes: 7

Rajan Kali
Rajan Kali

Reputation: 12953

You can create your own TextField Widget with desired color and use it across all places,

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

Now start using ColoredTextField instead of TextField and by changing color in your Widget, it gets applied to all the places.

Upvotes: 4

Related Questions