TextButton default color in dark theme

Viewed 334

Trying to change the default color for all TextButtons in my Android app w/ material. I see that I can style a "materialButtonStyle" and "materialButtonOutlinedStyle". However I do not see an attribute for a text button, possible something like "materialButtonTextStyle"

<style name="AppTheme" parent="Theme.MaterialComponents">
  <item name="materialButtonStyle">@style/myButton</item>
  <item name="materialButtonOutlinedStyle">@style/myButtonOutlined</item>
</style>

Example button:

<Button
    android:id="@+id/my_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    style="@style/Widget.MaterialComponents.Button.TextButton"
    android:text="Text Button" />

Is it possible to change the style globally for all material text buttons?

EDIT: Tried this from the theming-buttons material docs.

<style name="AppTheme" parent="Theme.MaterialComponents">
  <item name="borderlessButtonStyle">@style/Widget.App.Button.TextButton</item>
</style>

<style name="Widget.App.Button.TextButton" parent="Widget.MaterialComponents.Button.TextButton">
    <item name="materialThemeOverlay">@style/ThemeOverlay.App.Button.TextButton</item>
</style>

<style name="ThemeOverlay.App.Button.TextButton" parent="">
    <item name="colorPrimary">@color/md_purple_600</item>
</style>

However still not styling the text color for all text buttons.

3 Answers

As per the Buttons -Material design documentation the TextButton has a default style theme attribute ?attr/borderlessButtonStyle which can be used in the AppTheme to change the style globally for all material text buttons.

To change the Text Colour globally for all TextButtons:

1.Define the borderlessButtonStyle attribute in the Light and Night AppTheme like the below:

<!-- Base application theme. -->
<style name="MyAppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
  <item name="borderlessButtonStyle">@style/Widget.App.Button.TextButton</item>
</style>

<!-- For TextButton-->
<style name="Widget.App.Button.TextButton" parent="Widget.MaterialComponents.Button.TextButton">
  <item name="materialThemeOverlay">@style/ThemeOverlay.App.Button.TextButton</item>
</style>

<style name="ThemeOverlay.App.Button.TextButton" parent="">
  <item name="colorPrimary">@android:color/holo_red_dark</item>
</style> 

2.In every TextButton xml layout define the style style="?attr/borderlessButtonStyle" like the below:

<Button
    style="?attr/borderlessButtonStyle"
    android:id="@+id/text_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Text Button" />

And the Text colour will be changed globally based to the colorPrimary which is defined in Light/Night Theme.

Following the same way you can achieve the same for the other Material Button Styles like OutlinedButton and the default Button like:

<!-- Base application theme. -->
<style name="MyAppTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    <item name="borderlessButtonStyle">@style/Widget.App.Button.TextButton</item>
    <item name="materialButtonOutlinedStyle">@style/Widget.App.Button.OutlinedButton</item>
    <item name="materialButtonStyle">@style/Widget.App.Button</item>
</style>


<!-- For TextButton-->
<style name="Widget.App.Button.TextButton" parent="Widget.MaterialComponents.Button.TextButton">
    <item name="materialThemeOverlay">@style/ThemeOverlay.App.Button.TextButton</item>
</style>

<style name="ThemeOverlay.App.Button.TextButton" parent="">
    <item name="colorPrimary">@android:color/holo_red_dark</item>
</style>

<!-- For OutlinedButton-->
<style name="Widget.App.Button.OutlinedButton" parent="Widget.MaterialComponents.Button.OutlinedButton">
    <item name="materialThemeOverlay">@style/ThemeOverlay.App.Button.OutlinedButton</item>
</style>

<style name="ThemeOverlay.App.Button.OutlinedButton" parent="">
    <item name="colorPrimary">@android:color/holo_orange_dark</item>
</style>

<!-- For Button -->
<style name="Widget.App.Button" parent="Widget.MaterialComponents.Button">
    <item name="materialThemeOverlay">@style/ThemeOverlay.App.Button</item>
</style>

<style name="ThemeOverlay.App.Button" parent="">
    <item name="colorPrimary">@android:color/holo_blue_dark</item>
    <item name="colorOnPrimary">@android:color/holo_blue_bright</item>
</style>

And each Button listens to the above global attributes:

<Button
    style="?attr/borderlessButtonStyle"
    android:id="@+id/text_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Text Button" />

<Button
    style="?attr/materialButtonOutlinedStyle"
    android:id="@+id/outlined_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Outlined Button" />

<Button
    android:id="@+id/default_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Default Button" />

Below is a sample result for each Button Style in Light mode:

light_mode

And below is a sample result for each Button Style in Night mode:

dark_mode

As you can see from textButtonColors, TextButton use the primary color of your MaterialTheme as default content color.

@Composable
fun textButtonColors(
    backgroundColor: Color = Color.Transparent,
    contentColor: Color = MaterialTheme.colors.primary,
    disabledContentColor: Color = MaterialTheme.colors.onSurface
        .copy(alpha = ContentAlpha.disabled)
): ButtonColors = DefaultButtonColors(
    backgroundColor = backgroundColor,
    contentColor = contentColor,
    disabledBackgroundColor = backgroundColor,
    disabledContentColor = disabledContentColor
)

To achieve your goal, if you don't change your primary color, you can define a custom theme and override the style of your text buttons.

@Composable
fun CustomTextButtonStyle(content: @Composable () -> Unit) {
    MaterialTheme(
        colors = MaterialTheme.colors.copy(
            primary = Color.Green // Set your custom color
        )
    ) {
        content()
    }
}
CustomTextButtonStyle() {
    TextButton(onClick = { }) {
        Text(text = "Hello")
    }
}

In the title it says you want to define textColor for a dark theme. Did you define the theme in values-night so your app will take these values if the phone is in dark mode.

Related