Deep dive into FloatingActionButton in Flutter: Part 1

Share this post

You can find part 2 here

FloatingActionButton is a very useful Widget in a MaterialApp. It usually is (and should be) used as a primary action in a Scaffold, which is a top-level container in MaterialApp.

In this post, I want to talk about how to use FloatingActionButtons and explore their possibilities as much as I can.

Flutter made it very easy to use FloatingActionButton to any page that has a Scaffold as a top-level container:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FloatingActionButtons"),
      ),
      body: Center(
        child: Text('mrflutter.com'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }

The default position is always bottom right corner of the page and the default background color comes from primarySwatch or primaryColor of the theme of the MaterialApp class.

FloatingActionButton with default colour and positioning

If you want to use the smaller version of the FAB you can set mini: true.

How to change FloatingActionButton’s position

For this we can use FloatingActionButtonLocation which has the following options:

  • centerDocked
  • centerFloat
  • endDocked
  • endFloat
  • endTop
  • miniStartTop
  • startTop

Start, center and end speak for themselves as they simply position the FAB accordingly. The interesting part is docked and float ones which come in handy when FAB is used together with BottomNavigationBar. Docked means that the center of FAB will nicely align with the top of the BottomNavigationBar and float means that FAB will be positioned above the BottomNavigationBar.

FloatingActionButtonLocation.centerDocked

Here’s the code I have used for the screenshot:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FloatingActionButtons"),
      ),
      body: Center(
        child: Text('mrflutter.com'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      bottomNavigationBar: BottomAppBar(
        child: Container(
          height: 50.0,
        ),
      ),
    );
  }

If you would like to align the FAB with the AppBar, just use startTop or endTop as location.

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FloatingActionButtons"),
        backgroundColor: Colors.purple,
      ),
      body: Center(
        child: Text('mrflutter.com'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.startTop,
    );
  }

It will then look like this:

FloatingActionButtonLocation.startTop

How to use FloatingActionButton.extended

If you want to add text to your FAB, there is a wider version that supports a text label together with an icon. Obviously, label becomes a mandatory parameter, but icon becomes optional. The child parameter goes away as it can now contain multiple widgets.

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FloatingActionButtons"),
      ),
      body: Center(
        child: Text('mrflutter.com'),
      ),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: () {},
        tooltip: 'Tap to call',
        label: Text('CALL'),
        icon: Icon(Icons.call),
      ),
    );
  }

This will look like this:

FloatingActionButton.extended
FloatingActionButton.extended

I hope this post helped you do more with FloatingActionButtons. In the next part, I will explain what you can do with FABs and animations.

StatelessWidget vs StatefulWidget in Flutter

Share this post

In Flutter everything is a Widget. Whether it’s a Button or a whole page consisting of many elements. Web developers and especially React developers should see Widgets as Components. These Widgets could be something simple like a Button or an Image or something more advanced like a Counter widget.

A simple Button or an Image widget simply show information and don’t need to be re-rendered once shown. That means that the value they hold is not necessarily updated. However, a counter widget needs to update some number.

The following SimpleButton class represents a button with a text and a press callback function:

class SimpleButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
     child: Text("Press me"),
     onPressed() {
      print("Pressed!")
     },
    );
  }
}

Of course, we could customize the button as much as we want, but it will stay a StatelessWidget.

Now let’s try and make some changes to the same widget to make it Stateful:

class SimpleButtonCounter extends StatefulWidget {
  @override
  SimpleButtonCounterState createState() => SimpleButtonCounterState();
}
class SimpleButtonCounterState extends State<SimpleButtonCounter>() {

  int _counter = 0;

  @override
  initState() {
    super.initState();
   // we could also initialise the counter here
   // _counter = 0;
  }

  @override
  Widget build(BuildContext context) {
    return RaisedButton(
     child: Text("Pressed ${_counter} times"),
     onPressed() {
      setState(() {
       _counter++;
      });
     },
    );
  }
}

setState() is the key here. Every time we want to change the value that was used in our build() method, we need to call setState(). Otherwise, the build() method won’t be called and the change won’t be visible. To compare with React and Vue, you could think of StatelessWidget as a Functional Component and StatefulWidget as a “normal” component.

In my future posts, I will post about common things you should know to create your first application with Flutter.