FloatingActionButton example with Support Library
Solution 1
So in your build.gradle
file, add this:
compile 'com.android.support:design:27.1.1'
AndroidX Note: Google is introducing new AndroidX extension libraries to replace the older Support Libraries. To use AndroidX, first make sure you've updated your gradle.properties
file, edited build.gradle
to set compileSdkVersion
to 28
(or higher), and use the following line instead of the previous compile
one.
implementation 'com.google.android.material:material:1.0.0'
Next, in your themes.xml
or styles.xml
or whatever, make sure you set this- it's your app's accent color-- and the color of your FAB unless you override it (see below):
<item name="colorAccent">@color/floating_action_button_color</item>
In the layout's XML:
<RelativeLayout
...
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.design.widget.FloatingActionButton
android:id="@+id/myFAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_plus_sign"
app:elevation="4dp"
... />
</RelativeLayout>
Or if you are using the AndroidX material library above, you'd instead use this:
<RelativeLayout
...
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/myFAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:srcCompat="@drawable/ic_plus_sign"
app:elevation="4dp"
... />
</RelativeLayout>
You can see more options in the docs (material docs here) (setRippleColor
, etc.), but one of note is:
app:fabSize="mini"
Another interesting one-- to change the background color of just one FAB, add:
app:backgroundTint="#FF0000"
(for example to change it to red) to the XML above.
Anyway, in code, after the Activity/Fragment's view is inflated....
FloatingActionButton myFab = (FloatingActionButton) myView.findViewById(R.id.myFAB);
myFab.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
doMyThing();
}
});
Observations:
- If you have one of those buttons that's on a "seam" splitting two views (using a RelativeLayout, for example) with, say, a negative bottom layout margin to overlap the border, you'll notice an issue: the FAB's size is actually very different on lollipop vs. pre-lollipop. You can actually see this in AS's visual layout editor when you flip between APIs-- it suddenly "puffs out" when you switch to pre-lollipop. The reason for the extra size seems to be that the shadow expands the size of the view in every direction. So you have to account for this when you're adjusting the FAB's margins if it's close to other stuff.
-
Here's a way to remove or change the padding if there's too much:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) myFab.getLayoutParams(); p.setMargins(0, 0, 0, 0); // get rid of margins since shadow area is now the margin myFab.setLayoutParams(p); }
-
Also, I was going to programmatically place the FAB on the "seam" between two areas in a RelativeLayout by grabbing the FAB's height, dividing by two, and using that as the margin offset. But myFab.getHeight() returned zero, even after the view was inflated, it seemed. Instead I used a ViewTreeObserver to get the height only after it's laid out and then set the position. See this tip here. It looked like this:
ViewTreeObserver viewTreeObserver = closeButton.getViewTreeObserver(); if (viewTreeObserver.isAlive()) { viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { closeButton.getViewTreeObserver().removeGlobalOnLayoutListener(this); } else { closeButton.getViewTreeObserver().removeOnGlobalLayoutListener(this); } // not sure the above is equivalent, but that's beside the point for this example... RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) closeButton.getLayoutParams(); params.setMargins(0, 0, 16, -closeButton.getHeight() / 2); // (int left, int top, int right, int bottom) closeButton.setLayoutParams(params); } }); }
Not sure if this is the right way to do it, but it seems to work.
- It seems you can make the shadow-space of the button smaller by decreasing the elevation.
-
If you want the FAB on a "seam" you can use
layout_anchor
andlayout_anchorGravity
here is an example:<android.support.design.widget.FloatingActionButton android:layout_height="wrap_content" android:layout_width="wrap_content" app:layout_anchor="@id/appbar" app:layout_anchorGravity="bottom|right|end" android:src="@drawable/ic_discuss" android:layout_margin="@dimen/fab_margin" android:clickable="true"/>
Remember that you can automatically have the button jump out of the way when a Snackbar comes up by wrapping it in a CoordinatorLayout.
More:
- Google's Design Support Library Page
- the FloatingActionButton docs
- "Material Now" talk from Google I/O 2015 - Support Design Library introduced at 17m22s
- Design Support Library sample/showcase
Solution 2
I just found some issues on FAB and I want to enhance another answer.
setRippleColor issue
So, the issue will come once you set the ripple color (FAB color on pressed) programmatically through setRippleColor
. But, we still have an alternative way to set it, i.e. by calling:
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
ColorStateList rippleColor = ContextCompat.getColorStateList(context, R.color.fab_ripple_color);
fab.setBackgroundTintList(rippleColor);
Your project need to has this structure:
/res/color/fab_ripple_color.xml
And the code from fab_ripple_color.xml
is:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="@color/fab_color_pressed" />
<item android:state_focused="true" android:color="@color/fab_color_pressed" />
<item android:color="@color/fab_color_normal"/>
</selector>
Finally, alter your FAB slightly:
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_action_add"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
app:fabSize="normal"
app:borderWidth="0dp"
app:elevation="6dp"
app:pressedTranslationZ="12dp"
app:rippleColor="@android:color/transparent"/> <!-- set to transparent color -->
For API level 21 and higher, set margin right and bottom to 24dp:
...
android:layout_marginRight="24dp"
android:layout_marginBottom="24dp" />
FloatingActionButton design guides
As you can see on my FAB xml code above, I set:
...
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
app:elevation="6dp"
app:pressedTranslationZ="12dp"
...
-
By setting these attributes, you don't need to set
layout_marginTop
andlayout_marginRight
again (only on pre-Lollipop). Android will place it automatically on the right corned side of the screen, which the same as normal FAB in Android Lollipop.android:layout_alignParentBottom="true" android:layout_alignParentRight="true"
Or, you can use this in CoordinatorLayout
:
android:layout_gravity="end|bottom"
- You need to have 6dp
elevation
and 12dppressedTranslationZ
, according to this guide from Google.
Solution 3
FloatingActionButton
extends ImageView
. So, it's simple as like introducing an ImageView
in your layout. Here is an XML sample.
<android.support.design.widget.FloatingActionButton xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/somedrawable"
android:layout_gravity="right|bottom"
app:borderWidth="0dp"
app:rippleColor="#ffffff"/>
app:borderWidth="0dp"
is added as a workaround for elevation issues.
Solution 4
for AndroidX use like
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_add" />
Solution 5
If you already added all libraries and it still doesn't work use:
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_add"
/>
instead of:
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_add"
/>
And all will work fine :)
Anggrayudi H
Check my Android apps here. View my LinkedIn profile.
Updated on September 02, 2020Comments
-
Anggrayudi H over 3 years
Recently, I read these posts:
But, none of them give me a detail example about creating a new
FloatingActionButton
. It's so hard to understand, which is why I am asking this question.Can anyone give me an example about it?
EDIT
I just found some issues on
FloatingActionButton
(FAB), and I want to improve another answer. See my answer below. -
joshas almost 9 yearsSetting "colorAccent" color sets the same color to other controls. Is there a way to set different color for FAB?
-
fattire almost 9 yearsSure. Just add
android:backgroundTint="#FF0000"
for example to to the FloatingActionBar in the XML. (adding to answer) -
fattire almost 9 yearsCool. Can someone else confirm/advise? I tested w/"android:" and it worked.. but maybe app: is a better way to do it...?
-
Dark Leonhart almost 9 years@fattire Just wondering, can we add a Quick Return effect for FAB using design support library?
-
shalafi almost 9 yearsactually I am getting a crash when using android:backgroundTint in the xml for overriding the accent color, but app:backgroundTint seems to work fine (tested on Lollipop)
-
fattire almost 9 yearsHmm. Okay I'll change it above then. Thanks! Dark Leonhart-- I haven't seen anything about quick return built-in but there are samples of doing it elsewhere on stackoverflow that I presume will still work. Plus some libraries are available that do it as well.
-
Joao Sousa almost 9 yearsThis component, as of 22.2.0, in my opinion, is not production ready. Btw, may be a typo, but don't use
sp
in the evelation property. It should beapp:elevation="4dp"
-
Joao Sousa almost 9 yearsthumbs up for the research involved. plus 1 for the
pressedTranslationZ
. I didn't know that. -
fattire almost 9 yearsJoao yeah it has some issues-- changed sp to dp in example above, thx for the catch...
-
ianhanniballake almost 9 yearsNote if you are adding a
FloatingActionButton
to aCoordinatorLayout
, you can useapp:layout_anchor="element_with_seam"
andapp:layout_anchorGravity="bottom|right|end"
to position the FAB correctly over a seam - see the activity_detail layout from cheesesquare -
ianhanniballake almost 9 years@DarkLeonhart - check out my example of showing/hiding the FAB on scroll by extending its behavior.
-
Knoxie almost 9 yearsWhat if you're using ecplise? I've added the support library to the project but keep getting errors. It says it can't find any 'app:...' properties and if I remove those it wont build still.
-
fattire almost 9 years@Knoxie Not using eclipse any more, but be sure you have the
xmlns:app="http://schemas.android.com/apk/res-auto"
part in a ViewGroup that contains the FAB. -
Thiago almost 9 yearsapp:elevation="6dp" app:pressedTranslationZ="12dp" does the trick for pre-lollipop, but my fab is literally on the corner of screen on Lollipop
-
e.shishkin almost 9 yearsYou are using an incorrect value for "pressedTranslationZ". It's not the value of elevation on pressed state. PressedElevation = elevation + pressedTranslationZ. So correct values is app:elevation="6dp" app:pressedTranslationZ="6dp"
-
MBH over 8 yearshow about background color in xml ?
-
Christian García over 8 yearsActually you don't need to set the
app:elevation
andapp:pressedTranslationZ
values. Their default value is the one defined in the Material design guidelines. Anyway, e.shishkin is right, the values areapp:elevation:6dp
andpressedTranslationZ:6dp
. You can check it in the com.android.support.design source code -
android developer about 8 yearsWhat about the color of pressing the FAB ?
-
IainCunningham over 5 yearsWhat's the equivalent of '<android.support.design.widget.FloatingActionButton' in AndroidX? If i try to use the code above with "implementation 'com.google.android.material:material:1.0.0'" then I get a "Didn't find class" error at runtime.
-
Richard Barraclough almost 4 yearsThe button appears at the top left of the screen, but isn't it supposed to be at the bottom right?