How to create a circular outlined Material Button in Android?
T

3

38

I am trying to create a button with an icon in the center. The top and bottom part of the circle are a little flat. Is there a way to do this without using corner radius? Here is my layout for the button.

<com.google.android.material.button.MaterialButton
        android:id="@+id/start_dispenser_btn"
        style="@style/Widget.MaterialComponents.Button.OutlinedButton"
        android:layout_width="175dp"
        android:layout_height="175dp"
        android:padding="14dp"
        app:cornerRadius="150dp"
        app:icon="@drawable/ic_play_arrow_black_60dp"
        app:iconGravity="end"
        app:iconSize="150dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/stop_dispenser_btn"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/test_dispenser_container"
        app:strokeColor="@color/background_black" />

enter image description here

Total answered 23/10, 2019 at 19:13 Comment(1)
@Md.Asaduzzaman why not? Check also my answer. It doesn't need a custom background. Just use the app:shapeAppearanceOverlay attr.Transfuse
T
67

You can use the app:shapeAppearanceOverlay attribute to define the corner size. You can use the 50% value.

<com.google.android.material.button.MaterialButton
    android:layout_width="50dp"
    android:layout_height="50dp"
    style="@style/Widget.MaterialComponents.Button.OutlinedButton.Icon"
    app:icon="@drawable/ic_add_24px"
    app:iconSize="24dp"
    app:iconGravity="textStart"
    android:padding="0dp"
    app:iconPadding="0dp"
    android:insetLeft="0dp"
    android:insetTop="0dp"
    android:insetRight="0dp"
    android:insetBottom="0dp"
    app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MyApp.Button.Circle"
    />

with:

  <style name="ShapeAppearanceOverlay.MyApp.Button.Circle" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">50%</item>
  </style>

enter image description here

or with the style="@style/Widget.MaterialComponents.Button.Icon"

enter image description here

It requires at least the version 1.1.0.


With jetpack compose you can use the OutlinedButton applying a CircleShape as shape:

    OutlinedButton(onClick = { /* ... */ },
        modifier= Modifier.size(50.dp), // it is important otherwise the button is oval
        shape = CircleShape,
        border= BorderStroke(1.dp, Color.Blue),
        contentPadding = PaddingValues(0.dp),
        colors = ButtonDefaults.outlinedButtonColors(contentColor =  Color.Blue)
    ) {
            Icon(Icons.Default.Add, contentDescription = "content description")
    }

enter image description here

Transfuse answered 23/10, 2019 at 19:24 Comment(5)
Great solution! I wasn't able to find anywhere in the documentation where it states we can use percentages for the cornerSize attribute - thanks for this answer. For others who find this answer, it's important to define the insets individually (left, right, etc.) or they won't be applied.Lansing
It's weird that as soon as I put this button, I get IllegalArgumentException: The style on this component requires your app theme to be Theme.MaterialComponents (or a descendant). My app theme already has a parent Theme.MaterialComponents.Light.DarkActionBar. I had to explicitly set android:theme="@style/AppTheme" on this button to get rid of this error. Really weird.Bridget
@ShivamPokhriyal Post a question with all details. It is not related to this button.Transfuse
Thank you! I didn't realize you could use percentages instead of explicit values.Schoolmistress
This is fantastic. Period.Outsoar
C
23

By using cornerRadius along with inset you can get the rounded shape:

<com.google.android.material.button.MaterialButton
    style="@style/Widget.MaterialComponents.Button.OutlinedButton.Icon"
    android:layout_width="48dp"
    android:layout_height="48dp"
    app:cornerRadius="30dp"
    android:insetTop="0dp"
    android:insetBottom="0dp"
    android:insetLeft="0dp"
    android:insetRight="0dp"
    app:icon="@drawable/ic_menu"/>
Countrywide answered 27/1, 2020 at 15:3 Comment(4)
Easy) thank you. Works much better than styles and Icon shapes.Sarmiento
this Widget.MaterialComponents.OutlinedButton.Icon style is undefined for me.Endocrine
@Endocrine They changed it to "Widget.MaterialComponents.Button.OutlinedButton.Icon"Countrywide
What's the relationship of 30dp to 48dp?Teen
U
1

my answer is the enhancement of above answers. to build reusable resource :

<style name="ShapeAppearance.MdcShapeAppearance.SmallComponent.OutlinedCircleButton" parent="Widget.MaterialComponents.Button.OutlinedButton.Icon">
    <item name="android:insetLeft">@dimen/dip_0</item>
    <item name="android:insetRight">@dimen/dip_0</item>
    <item name="android:insetTop">@dimen/dip_0</item>
    <item name="android:insetBottom">@dimen/dip_0</item>
    <item name="android:padding">@dimen/dip_0</item>
    <item name="iconGravity">textStart</item>
    <item name="iconPadding">@dimen/dip_0</item>
</style>

then, you can use it as button style. don't forget to add app:cornerRadius="@dimen/dip_20" to make it circle with your desired size

<com.google.android.material.button.MaterialButton
        android:id="@+id/btn_plus"
        style="@style/ShapeAppearance.MdcShapeAppearance.SmallComponent.OutlinedCircleButton"
        android:layout_width="@dimen/dip_20"
        android:layout_height="@dimen/dip_20"
        app:cornerRadius="@dimen/dip_20"
        android:layout_marginEnd="@dimen/dip_16"
        app:icon="@drawable/ic_plus"
        app:iconTint="?colorOnBackground"
        app:layout_constraintBottom_toBottomOf="@id/tv_total_checkout_product"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@id/tv_total_checkout_product"
        app:strokeColor="?colorOnBackground" />
Usual answered 3/8, 2021 at 0:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.