104

I'm trying to figure out how can be modified FloatingActionButton from android support library. Can it be used with the text instead of image?

Something like this one:

enter image description here

I see it extends ImageButton so I think not. Am I right?

Is this correct in terms of Material Design in general?

comrade
  • 4,590
  • 5
  • 33
  • 48

12 Answers12

114

Thanks to all.

Here is easy workaround which I found for this question. Works correctly for Android 4+, for Android 5+ is added specific parameter android:elevation to draw TextView over FloatingActionButton.

<FrameLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|right">

    <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@android:color/transparent" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="@android:string/ok"
        android:elevation="16dp"
        android:textColor="@android:color/white"
        android:textAppearance="?android:attr/textAppearanceMedium" />
</FrameLayout>
comrade
  • 4,590
  • 5
  • 33
  • 48
64

convert a text into bitmap and use it. its super easy.

fab.setImageBitmap(textAsBitmap("OK", 40, Color.WHITE));

//method to convert your text to image
public static Bitmap textAsBitmap(String text, float textSize, int textColor) {
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setTextSize(textSize);
    paint.setColor(textColor);
    paint.setTextAlign(Paint.Align.LEFT);
    float baseline = -paint.ascent(); // ascent() is negative
    int width = (int) (paint.measureText(text) + 0.0f); // round
    int height = (int) (baseline + paint.descent() + 0.0f);
    Bitmap image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(image);
    canvas.drawText(text, 0, baseline, paint);
    return image;
}
sorak
  • 2,607
  • 2
  • 16
  • 24
Nandan Singh
  • 1,089
  • 12
  • 13
  • 2
    Perfect but text size is not changing. – Ankur_009 Sep 06 '17 at 06:41
  • 1
    @Ankur_009 its changing. Try increasing the value by quite a size as its in float. – pratz9999 Sep 09 '17 at 22:02
  • sweet, with few changes I made it work to convert icon fonts to drawables – Desolator Oct 08 '17 at 07:52
  • 1
    @Ankur_009: The button space is limited, that is why you do not see a change in text size. So if your text is already taking the full space on the button, making the text bigger will have no effect. – j3App Mar 08 '18 at 11:10
  • 2
    @pratz9999 i even set it to 1000 but still its not changing – Shivam Pokhriyal Jul 29 '18 at 11:48
  • @ShivamPokhriyal Please share the code in some online text editor so that I can help. – pratz9999 Jul 30 '18 at 19:20
  • @pratz9999 i used the exact same code. i am attaching my fab xml – Shivam Pokhriyal Jul 30 '18 at 19:42
  • @ShivamPokhriyal can you share the implementation of it in java? – pratz9999 Aug 01 '18 at 12:51
  • @pratz9999 Here is the code.. createButton = view.findViewById(R.id.teacher_create_notice); createButton.setImageBitmap(textAsBitmap(" + ", 32.f, getResources().getColor(R.color.colorPrimary))); I tried every possible value for textsize from 20, 20.0, 200, 200.0 etc. Still no result. – Shivam Pokhriyal Aug 01 '18 at 21:38
  • @ShivamPokhriyal It is working fine. You have to either increase the width and height of FAB or follow the URL below to increase the drawable area in FAB. https://stackoverflow.com/questions/27484126/adjust-icon-size-of-floating-action-button-fab – pratz9999 Aug 03 '18 at 13:27
  • @pratz9999 thanks for the link will surely give it a try. – Shivam Pokhriyal Aug 03 '18 at 13:36
48

With API 28 you can simply add text to Fabs using:

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

 <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_margin="8dp"
      android:contentDescription="@string/extended_fab_content_desc"
      android:text="@string/extended_fab_label"
      app:icon="@drawable/ic_plus_24px"
      app:layout_anchor="@id/app_bar"
      app:layout_anchorGravity="bottom|right|end"/>
Job M
  • 3,331
  • 2
  • 19
  • 26
33

FABs are usually used in CoordinatorLayouts. You can use this:

<android.support.design.widget.CoordinatorLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">

    <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="@dimen/fab_margin"               
            app:backgroundTint="@color/colorPrimary" />

      <TextView android:layout_height="wrap_content"
              android:layout_width="wrap_content"
              android:text="OK"
              android:elevation="6dp"
              android:textSize="18dp"
              android:textColor="#fff"
              app:layout_anchor="@id/fab"
              app:layout_anchorGravity="center"/>

</android.support.design.widget.CoordinatorLayout>

This is what does the work

app:layout_anchor="@id/fab"
app:layout_anchorGravity="center"

Result:

The Result

If you're using some layout_behavior for your FAB, you'll have to make a similar layout_behavior for the TextView

lokeshrmitra
  • 486
  • 6
  • 8
21

You can't set text for FloatingActionButton from the support library, but what you can do, is create a text image directly from android studio : File -> New -> Image Asset, and then use it for your button.

In the terms of Material Design; they didn't mention using text with FloatingActionButton, and I don't see any reason for doing that since you don't really have much space for a text.

aleksandrbel
  • 1,422
  • 3
  • 20
  • 38
Mulham Raee
  • 313
  • 1
  • 8
10

I was needing text in a FAB but instead I just went with a TextView with a circular drawable background:

  <TextView
        android:layout_margin="10dp"
        android:layout_gravity="right"
        android:gravity="center"
        android:background="@drawable/circle_background"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#FFF"
        android:textStyle="bold"
        android:fontFamily="sans-serif"
        android:text="AuthId"
        android:textSize="15dp"
        android:elevation="10dp"/>

Here is the drawable(circle_backgroung.xml):

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

<solid
    android:color="#666666"/>

<size
    android:width="60dp"
    android:height="60dp"/>
</shape>

enter image description here

Derwrecked
  • 771
  • 1
  • 6
  • 17
2

Answer of @NandanKumarSingh https://stackoverflow.com/a/39965170/5279156 works but i have made some changes with fab in code (not xml because they will be overwritten in class methods)

fab.setTextBitmap("ANDROID", 100f, Color.WHITE)
fab.scaleType = ImageView.ScaleType.CENTER
fab.adjustViewBounds = false

Where setTextBitmap is an extension for ImageView class with similar functionality but it supports multilne text

fun ImageView.setTextBitmap(text: String, textSize: Float, textColor: Int) {
    val paint = Paint(Paint.ANTI_ALIAS_FLAG)
    paint.textSize = textSize
    paint.color = textColor
    paint.textAlign = Paint.Align.LEFT
    val lines = text.split("\n")
    var maxWidth = 0
    for (line in lines) {
        val width = paint.measureText(line).toInt()
        if (width > maxWidth) {
            maxWidth = width
        }
    }
    val height = paint.descent() - paint.ascent()
    val bitmap = Bitmap.createBitmap(maxWidth, height.toInt() * lines.size, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(bitmap)
    var y = - paint.ascent()
    for (line in lines) {
        canvas.drawText(line, 0f, y, paint)
        y += height
    }
    setImageBitmap(bitmap)
}
Vlad
  • 7,997
  • 3
  • 56
  • 43
2

There is a new material view called ExtendedFloatingActionButton that does this.

Here's a code example:

    <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/add"
    android:layout_marginEnd="16dp"
    android:layout_marginBottom="16dp"
    android:clickable="true"
    android:focusable="true"
    app:icon="@drawable/ic_add_profile"
    app:rippleColor="@color/colorPrimary"
    app:layout_constraintBottom_toTopOf="@id/frameLayout_profilesAd"
    app:layout_constraintEnd_toEndOf="parent"
    android:contentDescription="@string/add_profile" />

This is the output:

enter image description here

You will need to add the material library to your dependencies, like so:

implementation 'com.google.android.material:material:1.5.0-alpha02'
RodXander
  • 643
  • 7
  • 12
1

A very little modification to comrade 's answer to support it for android API below 21 just add app:elevation="0dp" to the FloatingActionButton

This might help others!

1

I used a CardView to achieve the same result

  <androidx.cardview.widget.CardView
            android:layout_width="@dimen/dp80"
            android:layout_height="@dimen/dp80"
            android:layout_gravity="center_horizontal"
            app:cardElevation="@dimen/dp8"
            android:layout_marginBottom="@dimen/dp16"
            android:layout_marginTop="@dimen/dp8"
            app:cardBackgroundColor="@color/colorWhite100"
            app:cardCornerRadius="@dimen/dp40">

            <TextView
                style="@style/TextAppearance.MaterialComponents.Headline4"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_gravity="center_horizontal"
                android:background="@drawable/shape_go_bg"
                android:text="GO"
                android:gravity="center"
                android:textColor="@color/colorWhite100" />
        </androidx.cardview.widget.CardView>
1

It is available out of box.

The documentation here describes 3 types of FABs.

enter image description here

The most common Error, in this case, is an attempt to add text with FloatingActionButton. This is not how FAB is designed.

Use ExtendedFloatingActionButton when a LABEL is required.

 <!-- ExtendedFloatingActionButton to be used with TEXT.
   Note that it uses app:icon for icon image-->

  <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
    android:id="@+id/extended_fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="16dp"
    android:layout_gravity="bottom|right"
    android:contentDescription="@string/extended_fab_content_desc"
    android:text="@string/extended_fab_label"
    app:icon="@drawable/ic_plus_24px"/>


  <!-- FloatingActionButtonto be used when there is no text required.
   Note that it uses app:srcCompat and not the app:icon for icon image-->

  <com.google.android.material.floatingactionbutton.FloatingActionButton
      android:id="@+id/floating_action_button"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_gravity="bottom|right"
      android:layout_margin="16dp"
      android:contentDescription="@string/fab_content_desc"
      app:srcCompat="@drawable/ic_plus_24"/>
Sandeep Dixit
  • 799
  • 7
  • 12
0

Here is my own implementation, however I'm not using floating action button

This implementation is usefull for others instances:

Preview:

enter image description here

<FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="top|right"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <com.google.android.material.card.MaterialCardView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:minHeight="12dp"
                android:minWidth="12dp"
                app:cardCornerRadius="12dp"
                app:cardBackgroundColor="@color/colorPrimary"
                android:padding="4dp"
                android:src="@android:color/transparent">
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:elevation="16dp"
                    tools:text="+99"
                    android:textSize="9sp"
                    android:textAppearance="?android:attr/textAppearanceMedium"
                    android:textColor="@android:color/white" />
            </com.google.android.material.card.MaterialCardView>
        </FrameLayout>