Different ways to implement Floating Action Buttons in Flutter
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 anotherScaffold
instance for FAB only and nest multipleScaffold
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 withAlignment
. However, its placement is a bit different fromScaffold
.- Combination of
Stack
andPositioned
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 Alignment
and 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 :)