I'd like to create a MaterialButton programmatically and use the TextButton style on it.
I tried the following but the resulting button has a background color and is not a TextButton.
val newContext = ContextThemeWrapper(this, R.style.Widget_MaterialComponents_Button_TextButton)
val errorBtn = MaterialButton(newContext, null, R.style.Widget_MaterialComponents_Button_TextButton)
I tried many variants, (without using the 3 parameters constructor or without context wrapper).
I found this question: Apply Style to MaterialButton programmatically
But the answer is not satisfying as the setting background tint do not produce good results (there is a shadow being the button).
After reading the material design source, I discovered the following. The third parameter to MaterialButton is not a style resource but a style attribute. The parameter is called defStyleAttr and not defStyleRes, only the second one is equivalent to passing style in the XML file. And MaterialButton do not implement the 4 parameters constructor which takes this.
To clarify, a style resource is a "standalone" style definition, a style attribute is the name of the attribute in the context style. It is a bit weird that you are supposed to style a whole widget with one attribute, but this is how it works.
This means, we have to create and attribute that references the whole widget style and pass it when creating our button.
To do this, we have to:
attr resource in the app resources, by adding <attr name="myAttr" format="reference"/> to styles.xml.styles.xml, modify the app theme to use the attribute, like this:<style name="AppTheme" parent="Theme.MaterialComponents.NoActionBar">
<item name="myAttr">@style/Widget.MaterialComponents.Button.TextButton</item>
</style>
val errorBtn = MaterialButton(this, null, R.attr.myAttr)
This will work only if this (current context, usually an activity) has AppTheme applied to it (which should generally be the case). If this is not the case, or if you want to change the theme, it can be applied with ContextThemeWrapper, like so:
val ctx = ContextThemeWrapper(this, R.style.AppTheme)
val errorBtn = MaterialButton(ctx, null, R.attr.myAttr)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With