Apply Style to MaterialButton programmatically
I'm also facing the same issue. The only workaround I've found so far is to set the tint programmatically like:
button.setBackgroundTintList(ColorStateList.valueOf(Color.RED));
For a TextButton
there shouldn't be a background (just the text has a color). For a colored button, you should use the default Filled Button style which is Widget.MaterialComponents.Button
.
And when applied as a theme, the button uses different attributes. It's described in section Themed Attribute Mapping here: https://material.io/develop/android/components/material-button/
Filled button
+------------------------+-----------------------------------------+
| Component Attribute | Default Theme Attribute Value |
+------------------------+-----------------------------------------+
| android:textAppearance | textAppearanceButton |
| android:textColor | colorOnPrimary |
| iconTint | colorOnPrimary |
| rippleColor | colorOnPrimary at 32% opacity (pressed) |
| iconTint | colorOnPrimary |
| backgroundTint | colorPrimary |
| ... | ... |
+------------------------+-----------------------------------------+
In your case, the theme should look something like:
<style name="ButtonRedTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="colorPrimary">@color/red</item>
<item name="colorOnPrimary">@color/white</item>
<item name="colorOnSurface">@color/black</item>
</style>
You can also change all buttons to a specific style with
<item name="materialButtonStyle">@style/ButtonRedTheme</item>
in your app theme.
Using
MaterialButton(ContextThemeWrapper(context, R.style.ButtonRedStyle), attrs, defStyleAttr)
you are applying a themeoverlay to default style, you are not applying a different style.
It means:
<style name="ButtonRedTheme" parent="...">
<item name="colorPrimary">@color/...</item>
<item name="colorOnPrimary">@color/...</item>
<item name="colorSecondary">@color/...</item>
</style>
If you want to apply a different style you have to:
- Define a custom attribute in
attrs.xml
<attr name="myButtonStyle" format="reference"/>
- Assing a style to this attribute in your app theme:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
<item name="myButtonStyle">@style/CustomButtonStyle</item>
</style>
- Define the custom style:
<style name="CustomButtonStyle" parent="Widget.MaterialComponents.Button.*">
<item name="backgroundTint">@color/...</item>
<item name="rippleColor">@color/grey</item>
<item name="strokeWidth">1dp</item>
<item name="strokeColor">@color/black</item>
</style>
Finally use:
val customButton = MaterialButton(context, null, R.attr.myButtonStyle)
If you want to change your style for CustomView
, you've to pass it to constructor by passing it into third param defStyleAttr
like this:
class CustomRedButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = R.style.ButtonRedStyle // Just default style like this
) : MaterialButton(context, attrs, defStyleAttr)
and you can initialize it like this programmatically,
CustomRedButton(this, null, R.style.ButtonRedStyle) // Initialization, ('this' is context)
For more details refer here