Different ways to implement Floating Action Buttons in Flutter

Yuichi Fujiki
6 min readMar 16, 2023

--

Photo by Harmen Jelle van Mourik on Unsplash

Floating Action Button (often abbreviated as FAB) is one of the killer elements of Material Design. It is not only eye-catching but is also great for enhancing usability on scrollview-based screens. Even though the standard appearance of the Floating Action Button is an icon with a circle background, located on the bottom right of the screen, this appearance and placement can be quite flexible. In this article, I will mostly focus on the variety of placements of FAB.

Here is what I am going to cover.

What is Floating Action Button?

Most of you who are reading this article should be familiar with the concept, but Floating Action Button, which is frequently called FAB, is the button that sits in the same position on the screen and doesn’t move even if it’s background scrollview scrolls.

In the above video, I highlighted the FAB by surrounding it with a red rectangle, but the FAB part is actually the blue circle button with the “+” icon.

Types of FAB

There are four types of FABs defined in Material design (Material 2).

Small size:

FloatingActionButton.small(
child: const Icon(Icons.add),
onPressed: () {
print("Tapped small FAB");
},
)

Standard size:

This is the one that appeared in the video above.

FloatingActionButton(
child: const Icon(Icons.add),
onPressed: () {
print("Tapped small FAB");
},
)

Large size:

FloatingActionButton.large(
child: const Icon(Icons.add),
onPressed: () {
print("Tapped small FAB");
},
)

Extended comes with title and leading icon:

FloatingActionButton.extended(
onPressed: () {
print("Tapped extended FAB");
},
label: const Text("Tap on this"),
icon: const Icon(Icons.arrow_upward),
);

Have a look at how they look on-screen.

Implementation using Scaffold

It’s very easy to implement FAB using Scaffold class. It has floatingActionButton parameter in the constructor where you can feed the FloatingActionButton instance. The Scaffold class also prepares floatingActionButtonLocation parameter, where you can specify one of the predefined locations. The predefined locations are as follows.

Note that startXXX and endXXX would exchange their places for right-to-left language locale (e.g. Arabic). Below are some examples.

startTop :

Scaffold(
appBar: ...,
body: ...,
floatingActionButton: ...,
floatingActionButtonLocation: FloatingActionButtonLocation.startTop,
bottomAppBar: ...,
)

endFloat:

This is the standard location

Scaffold(
appBar: ...,
body: ...,
floatingActionButton: ...,
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
bottomAppBar: ...,
)

centerDocked:

Would be handy if you want to implement an interface like Instagram.

Scaffold(
appBar: ...,
body: ...,
floatingActionButton: ...,
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomAppBar: ...,
)

Implementation using Scaffold is super easy, especially if you need otherwise tricky placement like xxxTop/xxxDocked.

However, IMHO, the drawback is that it lacks flexibility in the following two points.

  • You need to be able to create FAB in the same file as the Scaffold. If you end up decoupling your scrollview-based widget to some other file, you cannot access the Scaffold easily. You CAN create another Scaffold instance for FAB only and nest multiple Scaffold instances as a result, but that is not recommended as per the official document.
  • The placement of the FAB is quite limited.

Implementation with Stack and Alignment

Instead of nesting Scaffold instances, we can make use of Stack. Stack stacks its children in the z-axis, and has alignment property where you can specify one of the predefined locations. The placement options are a little bit different though.

Some examples:

topLeft

Flexible(
child: Stack(
alignment: Alignment.topLeft,
children: [
ListView.builder(...), // Any ScrollView would do
Padding(
padding: const EdgeInsets.all(16),
child: floatingActionButton,
),
],
),
)

A nice detail is that I am wrapping the FAB with Padding. Otherwise, the FAB would look too close to the edges.

center:

Flexible(
child: Stack(
alignment: Alignment.center,
children: [
ListView.builder(...), // Any ScrollView would do
Padding(
padding: const EdgeInsets.all(16),
child: floatingActionButton,
),
],
),
)

bottomRight:

Stack(
alignment: Alignment.bottomRight,
children: [
ListView.builder(...), // Any ScrollView would do
Padding(
padding: const EdgeInsets.all(16),
child: floatingActionButton,
),
],
)

This approach is quite nice in that it doesn’t force our ScrollView to be in the same file as the Scaffold, and also it offers slightly different positioning with the same level of ease.

Implementation with Stack and Positioned

The previous approach was nice, but it was still limiting the FAB to the predefined set of locations within a view. Using Positioned widget, you can pretty much place the FAB in any place on the view. The following example allows you to drag the FAB to any location on the ScrollView, and the FAB stays in that place while the underlying ScrollView scrolls up & down.

double _top = 0;
double _left = 0;

...

Stack(
children: [
ListView.builder(...),
Positioned(
left: _left,
top: _top,
child: GestureDetector(
onPanUpdate: (details) {
setState(() {
_left += details.delta.dx;
_top += details.delta.dy;
});
},
child: floatingActionButton
),
),
],
)

Using this simple technique, you can implement something like the chat heads of Facebook (it may reveal my age 😂)

Material 3 design

I have covered pretty much what I wanted up to this point, but let me add a nice little trivia at the end. The current version of Flutter (3.7.x) uses Material 2 design. The Floating Action Button looks a little bit different in the Material 3 design. It will be more square-ish rather than a circle. There is a way to test the Material 3 design with the current version of Flutter. You can just specify useMaterial3: true in your MaterialApp instance and you’re good to go 👍🏻.

MaterialApp(
theme: ThemeData().copyWith(useMaterial3: true),
...
)

You would see Material 3 FABs like this.

Conclusion

In this article, I have covered the types and placements of Floating Action Button in Flutter development.

  • Even though Scaffold is the default way to implement it, and it has a quite nice way to place the button in otherwise tricky places, it imposes restrictions on how you structure your code, and where you place the button.
  • Stack offers equally easy implementation in combination with Alignment. However, its placement is a bit different from Scaffold.
  • Combination of Stack and Positioned basically allows you to place the FAB anywhere on your scrollview, which could boost your imagination/creativity.

You can find the code I explained in this article here.

There is much more you can explore on Floating Action Button. You can change the shape, you can use Alignmentand do pretty much the same thing as I did with Positioned , etc. Even though I think there are fewer use cases for them, it would be definitely fun to explore. If you come up with any interesting use case/customization of FAB, please let me know!!

Happy coding :)

--

--

Yuichi Fujiki

Technical director, Freelance developer, a Dad, a Quadriplegic, Life of Rehab