How to set a gradient background in a Material Button from Material Components?
From the documentation for MaterialButton
:
Do not use the
android:background
attribute. MaterialButton manages its own background drawable, and setting a new background meansMaterialButton
can no longer guarantee that the new attributes it introduces will function properly. If the default background is changed,MaterialButton
cannot guarantee well-defined behavior.
The only supported way to modify the background of the button is to set a color value to the app:backgroundTint
attribute. Unfortunately, gradients are not supported here either; you can only use a simple color value or a ColorStateList
.
So, there is no supported way to use a gradient background with MaterialButton.
I found this solution.
<com.google.android.material.button.MaterialButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/selector_gradient_example"
app:backgroundTint="@null" />
selector_gradient_example
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:color="@color/banana_yellow">
<item android:state_enabled="true">
<ripple android:color="@color/banana_yellow">
<item>
<shape android:shape="rectangle">
<gradient android:angle="135" android:endColor="@color/banana_yellow" android:startColor="@color/main_yellow" />
</shape>
</item>
</ripple>
</item>
<item android:state_enabled="false">
<shape android:shape="rectangle">
<gradient android:angle="315" android:endColor="#ede0be" android:startColor="#e0bf7e" />
</shape>
</item>
</selector>
Starting with the version 1.2.0-alpha06
you can use the android:background
attribute in the MaterialButton
.
<MaterialButton
app:backgroundTint="@null"
android:background="@drawable/button_gradient"
... />
Otherwise if you can't use the 1.2.0-alpha06 or higher you have to use the AppCompatButton
component.
Just a some tips about the MaterialButton
.
- Currently the
backgroundTint
is still the default MaterialButton style.
If you are using a customandroid:background
, you have to make sure to null outbackgroundTint
(eitherapp:backgroundTint="@null"
orapp:backgroundTint="@empty"
), to avoid that the custom background doesn't get tinted. - using a custom
android:background
the defaultMaterialShapeDrawable
is not used. Some features like stroke, shapeappearance, ripple are not set (since they are related to theMaterialShapeDrawable
) . You have to provide them with your custom background.
Make use of androidx.appcompat.widget.AppCompatButton
if you are using Material Theme to be able to apply background gradients, because Material Button doesn't offer support to it yet.
For background gradient, create 3 new resources in drawable
folder:
selector_btn.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- disabled state -->
<item android:drawable="@drawable/btn_gradient_inactive" android:state_enabled="false" />
<item android:drawable="@drawable/btn_gradient_active" />
</selector>
btn_gradient_inactive.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#01579B"
android:endColor="#1A237E"
android:angle="0" />
<corners android:radius="5dp"/> </shape>
btn_gradient_active.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#2196F3"
android:endColor="#3F51B5"
android:angle="0" />
<corners android:radius="5dp"/>
</shape>
In your styles.xml
:
<style name="BtnStyle" parent="Widget.AppCompat.Button.Borderless">
<item name="android:layout_marginStart">35dp</item>
<item name="android:layout_marginEnd">35dp</item>
<item name="android:background">@drawable/selector_btn_gradient</item>
<item name="android:textColor">@color/selector_text_color</item>
<item name="android:textAllCaps">false</item>
<item name="android:textSize">14sp</item>
</style>
In your layout.xml
file:
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/my_btn_id"
style="@style/BtnStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content" />