Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to shape a FAB to be rounded corners button (pill shape), similar to in contact-details screen of Contacts app?

Background

Initially, a FAB (floating action button) only had one shape : circle, and it only had the option to have an icon in it.

The problem

In the past year or so, Google added various screens in its apps, that show a FAB that changes its size. For example, if you open its Contacts app and choose a contact, you a FAB as such:

enter image description here

And if you scroll a bit, it gets to be a circle, with just the icon in it:

enter image description here

I want to know how to make such a FAB, and also use similar one with just an icon in the middle (without text), meaning a rounded corners one.

Something like that:

enter image description here

What I've tried and found

At first, I tried to just set the width of the FAB to be larger, but this didn't help, as it insisted on being a perfect circle (fit in a square, and without edges).

Seeing that maybe FAB can't handle this currently, I used MaterialCardViewinstead:

                <com.google.android.material.card.MaterialCardView

android:layout_width="60dp" android:layout_height="32dp" android:clickable="true" android:focusable="true" app:cardBackgroundColor="..." app:cardCornerRadius="16dp" >

                    <androidx.appcompat.widget.AppCompatImageView
                        android:layout_width="wrap_content" android:layout_height="wrap_content"
                        android:layout_gravity="center" app:srcCompat="..."/>
                </com.google.android.material.card.MaterialCardView>

This works, but the clicking effect is gone.

I also tried MaterialButton, but this doesn't support an icon in the middle, only on the various of the text inside.

Later, I've noticed that FAB actually does have a way to customize the shape of itself :

https://developer.android.com/reference/com/google/android/material/floatingactionbutton/FloatingActionButton#setshapeappearance

https://github.com/material-components/material-components-android/blob/master/lib/java/com/google/android/material/floatingactionbutton/FloatingActionButton.java

Also, as for the expanding FAB, I've found this:

https://developer.android.com/reference/com/google/android/material/floatingactionbutton/ExtendedFloatingActionButton

https://material.io/develop/android/components/extended-floating-action-button/

So looking at its code, I've found that it uses a shape of a pill, and I tried to do a similar thing to the normal FAB :

class PillFab @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
    FloatingActionButton(context, attrs, defStyleAttr) {
    init {
        val shapeAppearanceModel =
            ShapeAppearanceModel(context, attrs, defStyleAttr, DEF_STYLE_RES, ShapeAppearanceModel.PILL)
        shapeAppearance = shapeAppearanceModel
    }

    companion object {
        private val DEF_STYLE_RES = R.style.Widget_MaterialComponents_FloatingActionButton
    }
}

Sadly, this didn't work at all. It's still in a circle shape.

The question

How can I set a FAB (with clicking effect) that has rounded corners and a single icon inside?

like image 430
android developer Avatar asked Nov 26 '22 00:11

android developer


1 Answers

It is not the perfect answer because you are looking for an ExtendedFAB without text.

However you can obtain something similar using a MaterialButton changing the component’s shape using the attribute shapeAppearanceOverlay.

enter image description here

<com.google.android.material.button.MaterialButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MyApp.Button.Rounded"
            app:icon="@drawable/outline_cached_black_18dp"
            app:iconPadding="0dp"
            app:iconGravity="textStart"
            />

using:

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

Currenty the app:iconGravity doesn't support the center value. A workaround to center the icon is using these attrs:

            app:iconPadding="0dp"
            app:iconGravity="textStart"

If you would like to override some theme attributes from a default style now you can use new materialThemeOverlay attribute.

Something like:

<style name="MtButtonStyle"
 parent="Widget.MaterialComponents.Button">
   <item name=“materialThemeOverlay”>@style/MyButtonThemeOverlay</item>
</style>

<style name="MyButtonThemeOverlay">
  <item name="colorPrimary">@color/...</item>
  <item name="colorOnSurface">@color/....</item>
</style>
like image 131
Gabriele Mariotti Avatar answered Nov 28 '22 13:11

Gabriele Mariotti