When creating a MaterialButton in code and passing a style from styles.xml not all attributes apply to the button,. Specifically backgroundTint, iconTint, and textColor, although there may be others. When building the component from an xml layout all styling is applied correctly
Expected behavior: Styles should be applied as if they were created in xml
`val button = MaterialButton(newContext, null, R.style.Widget_Cladwell_Button_FilterCapsule)
`
Android API version: 29
Material Library version: 1.2.0-aplpha05
Hey there. Do you mind attaching a small project that demonstrates the problem you're describing? It's much easier for us to diagnose if we can look at how everything in your project is connected and what your theme/style/layout hierarchy looks like.
Thanks!
I have created repo that demonstrates this problem: https://github.com/alapshin/materialissue1183.
Screenshot that demonstrates it. First button uses style specified in xml, second button specifies style as constructor parameter
class AccentButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@AttrRes defStyleAttr: Int = R.attr.materialButtonStyle,
@StyleRes defStyleRes: Int = R.style.AccentButtonStyle
) : MaterialButton(wrap(context, attrs, defStyleAttr, defStyleRes), attrs, defStyleAttr) {
}

You can't assign a style using:
MaterialButton(wrap(context, attrs, defStyleAttr, defStyleRes), attrs, defStyleAttr)
TheMaterialThemeOverlay.wrapmethod uses the materialThemeOverlay attribute to create a themed context.
You apply a theme overlay using something like:
class AccentButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@AttrRes defStyleAttr: Int = R.attr.materialButtonStyle,
@StyleRes defStyleRes: Int = R.style.AccentButtonThemeOverlay
) : MaterialButton(ContextThemeWrapper(context, defStyleRes), attrs, defStyleAttr) {
}
with:
<style name="AccentButtonThemeOverlay" parent="">
<item name="materialThemeOverlay">@style/buttonoverlay</item>
</style>
<style name="buttonoverlay">
<item name="colorPrimary">@color/...</item>
</style>
If you want to create a custom button with a custom style you have to:
attrs.xml<attr name="myButtonStyle" format="reference"/> <style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
<item name="myButtonStyle">@style/AccentButtonStyle</item>
</style>
with:
<style name="AccentButtonStyle" parent="Widget.MaterialComponents.Button">
<item name="backgroundTint">@color/...</item>
<item name="icon">@drawable/....</item>
<item name="iconTint">@color/....</item>
</style>
and then use this constructor:
class AccentButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@AttrRes defStyleAttr: Int = R.attr.myButtonStyle
) : MaterialButton(context, attrs, defStyleAttr) {
}
So why does it work in xml layout? This seems like a lot of extra code/indirection to do something that works out of the box for non material components.
On Aug 2, 2020, at 5:18 PM, Gabriele Mariotti notifications@github.com wrote:

You can't assign a style using:
MaterialButton(wrap(context, attrs, defStyleAttr, defStyleRes), attrs, defStyleAttr)TheMaterialThemeOverlay.wrapmethod uses the materialThemeOverlay attribute to create a themed context.
You apply a theme overlay using something like:
class AccentButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@AttrRes defStyleAttr: Int = R.attr.materialButtonStyle,
@StyleRes defStyleRes: Int = R.style.AccentButtonThemeOverlay
) : MaterialButton(ContextThemeWrapper(context, defStyleRes), attrs, defStyleAttr) {
}
with:<style name="AccentButtonThemeOverlay" parent=""> <item name="materialThemeOverlay">@style/buttonoverlay</item> </style> <style name="buttonoverlay"> <item name="colorPrimary">@color/...</item> </style>If you want to create a custom button with a custom style you have to:
define an attribute in attrs.xml
assign in your app theme a value to this new attr:
with:
<style name="AccentButtonStyle" parent="Widget.MaterialComponents.Button"> <item name="backgroundTint">@color/...</item> <item name="icon">@drawable/....</item> <item name="iconTint">@color/....</item> </style>and then use this constructor:
class AccentButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@AttrRes defStyleAttr: Int = R.attr.myButtonStyle
) : MaterialButton(context, attrs, defStyleAttr) {
}
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub, or unsubscribe.
Unfortunately this is just a limitation of the Android framework. Using a theme overlay that sets the default widget style and wrapping the context passed into the constructor is the recommended approach.
Gotcha. Will give it a shot!! Thanks for the detailed explanation!
On Aug 3, 2020, at 8:48 AM, Dan Nizri notifications@github.com wrote:

Unfortunately this is just a limitation of the Android framework. Using a theme overlay that sets the default widget style and wrapping the context passed into the constructor is the recommended approach.—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub, or unsubscribe.
@gabrielemariotti your explanation is great! Thank you! I spent hours trying to achieve this and when I was about to give up I found this issue. It finally worked! Also thanks to @bryandunbar for asking this question 🎉
Most helpful comment
You can't assign a style using:
MaterialButton(wrap(context, attrs, defStyleAttr, defStyleRes), attrs, defStyleAttr)The
MaterialThemeOverlay.wrapmethod uses thematerialThemeOverlayattribute to create a themed context.You apply a theme overlay using something like:
with:
If you want to create a custom button with a custom style you have to:
attrs.xml<attr name="myButtonStyle" format="reference"/>with:
and then use this constructor: