Why should you use Material Button in Android?

Harjot Singh
5 min readMay 10, 2022

--

In the initial stages of Android Development, we all might have heard the term “Material”(in context of Android of course 😛). Since the beginning, I’ve been using Button but up until recently, I discovered the power of Material Button 🙌 .

Below, I’d be sharing the reasons why to use Material Button and after that how to implement it.

Let’s understand about Material Button class,

Material Button extends AppCompat Button which further extends Button class. Now, what’s an AppCompatButton?

It’s a button which supports features on older versions of platform. This is automatically used when one uses Button in layout.

Note: Use AppCompatButton explicitly when writing custom views.

This means Material Button would have new interesting attributes which are compatible with older Android versions.

Further reasons as to why Material Button:

Remember the time when you are using button and everything is set…the UI is ready and you are almost confident that the code would work. You run the project, it runs as expected but the button is not showing the touch feedback. You’d probably get uninterested and go to XML of the layout again and add:

android:foreground = “?attr/selectableItemBackground”

Problem solved? 🤔
Umm not exactly.
If the minSdk of the project is below 23, Android Studio throws a waring in XML that this attribute won’t work on older versions(below v23). So, how to fix for older versions? There are two options as per my current understanding:

a. Creating a rippleDrawable or shapeDrawable and then setting background for <Button>.

b. Using <MaterialButton>.

I believe doing a. would be a lot of work so let’s opt for b. and see how it can be done…

  • In <MaterialButton> there’s no need of creating ripple drawable. We can add the ripple color using the attribute:
android: rippleColor = “@color/…”

NOTE: The rippleColor opacity is 50%.

  • If the project is supposed to have dark theme and normal theme, then you are in luck my friend since Material Button will implicitly change its color according to the theme.

Let’s go through some points to take care of when implementing Material Button:

  • Do not use android:background attribute when using Material Button. It manages its own background drawable and adding a custom background drawable the button won’t function properly. So, what’s the solution?
    I hope you might have guessed by this time. If not, it’s okay it took me ages to guess it too 😅

Set it using backgroundTint attribute. This accepts either color or colorStateList. (More on colorStateList later)

  • If you’re using Theme.MaterialComponents theme, then <Button> is auto-inflated as <…..MaterialButton>. This means even if you use <Button> in your XML, it will work as <MaterialButton> internally. Ok, then why bother and use MaterialButton tag explicitly if internally it’s using MDC(Material Design Component)?

Simple explanation for the above point would be:
Since in <Button> we cannot use the power of MaterialButton attributes such as rippleColor, icon, cornerRadius and so on. But if you use MaterialButton, obviously you can use these attributes for more appealing button.

Enough talking, let’s do hands-on on the project:

IMPLEMENTATION:

First let’s take a look at what we are going to implement:

Preview of Implementation

We’ll go through 4 types of button. The difference would be in the styles. Notice how for different types of button, we use different styles.

Text Button

This button is pretty straightforward, the only difference would be in style.

<com.google.android.material.button.MaterialButton
android:id="@+id/text_btn"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Text Button"
android:textAllCaps="false"/>

Outlined Button

<com.google.android.material.button.MaterialButton
android:id="@+id/outlined_btn"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:letterSpacing="0.1"
android:text="Outlined Button"
app:strokeColor="@color/black"
app:strokeWidth="1dp" />
  • Notice the style used for this button type.
  • strokeWidth and strokeColor can be changed.

Contained Button

<com.google.android.material.button.MaterialButton
android:id="@+id/contained_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Contained Button"/>

Contained Button with Icon

  • Use .Icon suffix with the style only if the icon would be at start of the button. It adjusts padding slightly to achieve a better visual view.
  • You’ll be introduced to new attributes: insetTop & insetBottom.

When inset for top and bottom are set as 0dp, the view would look like the one at the left and by default, it looks like the one at the right i.e. with a little bit of internal padding.

Material button with inset as 0 dp and without inset
<com.google.android.material.button.MaterialButton
android:id="@+id/contained_btn_w_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:ellipsize="end"
android:insetTop="0dp"
android:insetBottom="0dp"
android:maxLines="1"
android:text="Contained Button W Icon"
app:backgroundTint="@color/teal_700"
app:cornerRadius="16dp"
app:icon="@drawable/ic_launcher_foreground"
app:iconGravity="top"/>

BONUS:

Let’s say if we were to add icon to the left and right of the content within button, this is how we’d do it:

a. For Icon to the left:

<com.google.android.material.button.MaterialButton
android:id="@+id/contained_btn_w_left_icon"
app:icon="@drawable/ic_android_black_24dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="48dp"
android:text="Contained Button"/>
  • If you want to add padding, it can be done using app:iconPadding attribute.

b. For Icon to the right:

<com.google.android.material.button.MaterialButton
android:id="@+id/contained_btn_w_right_icon"
app:icon="@drawable/ic_android_black_24dp"
app:iconGravity="end"
app:iconPadding="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="48dp"
android:text="Contained Button"/>
  • If your icon is end-aligned, you cannot use .Icon style and padding must be explicitly added.

Here’s the full XML code:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<com.google.android.material.button.MaterialButton
android:id="@+id/text_btn"
style="@style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Text Button"
android:textAllCaps="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<com.google.android.material.button.MaterialButton
android:id="@+id/outlined_btn"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:letterSpacing="0.1"
android:text="Outlined Button"
app:layout_constraintEnd_toEndOf="@id/text_btn"
app:layout_constraintStart_toStartOf="@id/text_btn"
app:layout_constraintTop_toBottomOf="@id/text_btn"
app:strokeColor="@color/black"
app:strokeWidth="1dp" />

<com.google.android.material.button.MaterialButton
android:id="@+id/contained_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:insetTop="0dp"
android:insetBottom="0dp"
android:text="Contained Button"
app:layout_constraintEnd_toEndOf="@id/outlined_btn"
app:layout_constraintStart_toStartOf="@id/outlined_btn"
app:layout_constraintTop_toBottomOf="@id/outlined_btn" />

<com.google.android.material.button.MaterialButton
android:id="@+id/contained_btn_w_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:ellipsize="end"
android:insetTop="0dp"
android:insetBottom="0dp"
android:maxLines="1"
android:text="Contained Button W Icon"
app:backgroundTint="@color/teal_700"
app:cornerRadius="16dp"
app:icon="@drawable/ic_launcher_foreground"
app:iconGravity="top"
app:layout_constraintEnd_toEndOf="@id/contained_btn"
app:layout_constraintStart_toStartOf="@id/contained_btn"
app:layout_constraintTop_toBottomOf="@id/contained_btn" />

</androidx.constraintlayout.widget.ConstraintLayout>

Thank you for reading so far! 😄

--

--

Harjot Singh

Android Developer @HealhifyMe I lose my handwritten notes often...so now making sure I can find my notes easily :p