A Deep Dive Into FloatingActionButton in Flutter

A tutorial to the power of FloatingActionButtons in Flutter

Deven Joshi
ProAndroidDev

--

This article is the third article in a series of articles meant for an in-detail study of Flutter widgets. After covering ListViews and TextFields in depth, we will now go into the FloatingActionButton widget in Flutter.

Introduction to FloatingActionButton

A FloatingActionButton in material design is a button on a screen that is tied to an obvious action which a user would usually do on that specific screen. This button floats above the content of the screen and usually resides on one corner of the screen.

For example, in Gmail, the main screen has a FloatingActionButton to compose emails. The purpose of the FAB must be something the user might frequently want or needs to do.

Types of FloatingActionButton in Flutter

Flutter offers two types of FloatingActionButtons out-of-the-box.

  1. FloatingActionButton
  2. FloatingActionButton.extended

1. FloatingActionButton

The default constructor creates a simple circular FAB with a child widget inside it. It takes an onPressed method to react to taps and a child (not compulsory) to display a widget inside the FAB.

A FAB using the default constructor

The code is relatively straightforward and is most often used with the floatingActionButton parameter of the Scaffold widget.

FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add),
),

2. FloatingActionButton.extended

FloatingActionButton.extended offers a wide FAB, usually with an icon and a label inside it.

A FAB using the .extended constructor

Instead of a child parameter, we now have label and icon parameters.

FloatingActionButton.extended(
onPressed: () {},
icon: Icon(Icons.save),
label: Text("Save"),
),

Dealing with Colors in a FloatingActionButton

The FAB offers the foregroundColor and backgroundColor parameters to color the elements inside it.

The foregroundColor colors the child inside the FAB.

FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add,),
foregroundColor: Colors.red,
),

The backgroundColor colors the background of the button.

FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add,),
backgroundColor: Colors.pink,
),

Note: Individual element colors will override the foregroundColor attribute.

If the icon inside has a user defined color and a foregroundColor at the same time, the icon color will override the foregroundColor.

FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add, color: Colors.yellow,),
foregroundColor: Colors.pink,
),
“+” icon turns yellow even with foregroundColor specifying pink

Changing the Look of the FloatingActionButton

The FAB gives us multiple options to resize and change the look of the button.

Switching to a mini button

In material design, the FAB has two sizes: default and mini. To switch to a mini size, set mini in the constructor to true.

floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add,),
mini: true,
),

This makes the button smaller in size.

Mini button

For comparison, here’s the earlier larger button.

Default button

Changing the shape of the FAB

To change the shape of the button, we set the shape parameter in the constructor. The default value of the shape is a CircleBorder().

Let’s make a square button instead of a round one.

floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add,),
shape: RoundedRectangleBorder(),
),
FAB using a RoundedRectangleBorder

If you notice, it says RoundedRectangleBorder but it behaves like a square. This is because we haven’t supplied a borderRadius.

Supplying a border radius,

floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add,),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0))),
),

RoundedRectangleBorder and other border classes also have another field called side which lets us edit the color and width of the border.

floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add,),
shape: RoundedRectangleBorder(side: BorderSide(color: Colors.pink, width: 4.0)),
),

You can also define your own border class to do custom borders.

You can do something like a DiamondBorder class and simple set the border to it. This example is taken from the Flutter Gallery application.

floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.add,),
shape: _DiamondBorder(),
),

Or you can just go crazy with it and do a random shape like this one. All you need is to define a new type of ShapeBorder.

FAB with custom border

Changing the elevation of FAB

We can change the effect of elevation of the FAB above the screen by setting the elevation and highlightElevation property. elevation works at all times while highlightElevation is the elevation of button when tapped.

Let’s set elevation to 0.0:

FAB with 0.0 elevation

And then 20.0

FAB with 20.0 elevation

You can see the shadow changing around the button indicating an increase in distance in the z-axis.

Animating the FloatingActionButton

This section is meant to cover some animations related to FloatingActionButtons.

Default FAB animation in page transitions

Before we go into something we can implement, I want to mention the default animation Flutter has when navigating between pages which both have a FloatingActionButton. When transitioning from one page to the other, Flutter will automatically animate the FAB change instead of switching instantly. We will see why this happens in the next section.

FAB transitions when we go from one page to the other

This requires no code on the user side.

IMPORTANT: Hero Animations with FloatingActionButtons

OR Why can’t I have two FloatingActionButtons on the same page?

This upper animation is possible because the FloatingActionButton has a Hero widget wrapped around it. A Hero is an element that flies to the next page when a transition occurs.

A Hero widget requires a tag that correlates two separate elements on two different pages and then makes one transition to the other.

The Hero tag has to be unique. Since each FAB is a Hero, defining two of them on the same page is not allowed without explicitly changing the hero tag of one of them.

Hence, defining two FABs on one page is not allowed. If we want to have two or more FABs, we need to set the heroTag parameter to another value.

floatingActionButton: FloatingActionButton(
onPressed: () {},
child: Icon(Icons.save),
heroTag: "demoValue",
),

Now, we can have another FAB on the same page as well.

Since we just said each FAB is a Hero, we can use the FAB to create Hero animations.

The code for the FAB would be:

floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => SomeOtherClass()));
},
child: Icon(
Icons.add,
),
heroTag: "demoTag",
),

We explicitly define the heroTag and supply the same hero tag to the “+” icon on the second page which we also wrap with a Hero widget.

Hero(
child: Icon(
Icons.add,
size: 100.0,
),
tag: "demoTag",
),

This makes the button transition to the icon. Note that now, a FAB on the second page would not affect us as we have changed the default Hero tag. So even if we had a FAB on the second page, the default transition would not take place.

There are a few other animations we can do with a FAB but those fall within the realm of a Scaffold and we’ll cover those when we get to the Scaffold deep dive.

That’s it for this article! I hope you enjoyed it, and leave a few claps if you did. Follow me for more Flutter articles and comment for any feedback you might have about this article.

Feel free to check out my other profiles and articles as well:

Twitter

GitHub

Some of my other articles

--

--