41

Created counter app with one floating action button.

If i want to add one more button for reset the counter, where can i add second floating action button at bottom bar?

Also i have to add any method in void section or is there any reset counter function available?

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Counter App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Counter App'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Text('You have pressed the button $_counter times.'),
      ),
      bottomNavigationBar: BottomAppBar(
        child: Container(
          height: 50.0,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => setState(() {
          _counter++;
            }),
        tooltip: 'Increment Counter',
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    );
  }
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
fluttertalk
  • 499
  • 1
  • 6
  • 13

7 Answers7

75

floatingActionButton property on Scaffold widget do not need to take FloatingActionButton widget necessarily. It can also take Column or Row widgets.

Below, I'm sharing my Scaffold widget example with two floating action buttons on top of each other.

return Scaffold(
  appBar: AppBar(
    title: Text(""),
  ),
  body: SingleChildScrollView(/*...*/),
  floatingActionButton: Column(
    mainAxisAlignment: MainAxisAlignment.end,
    children: [
      FloatingActionButton(
        child: Icon(
          Icons.delete
        ),
        onPressed: () {
          //...
        },
        heroTag: null,
      ),
      SizedBox(
        height: 10,
      ),
      FloatingActionButton(           
        child: Icon(
          Icons.star
        ),
        onPressed: () => _someFunc(),
        heroTag: null,
      )
    ]
  )
);
RaZzLe
  • 1,984
  • 3
  • 13
  • 24
  • Can you clarify what that ```heroTag: null``` means, I'm a bit confused about it? – sh_ark Sep 15 '21 at 11:34
  • 3
    `heroTag` is the tag to apply to the button's `Hero` widget. By default Flutter assumes that there should be only one `FloatingActionButton` per screen, and if one uses more than one FloatingActionButton on a screen then heroTags must be set explicitly. On above example I set them ´null´ as I didn't use any animations on those buttons. You can be set something like `heroTag: "heroTag1"` and on the other FloatingActionButton like `heroTag: "heroTag2"` if you are using Animations. For more details check this link: https://api.flutter.dev/flutter/material/FloatingActionButton-class.html – RaZzLe Sep 21 '21 at 06:10
  • in flutter documentation, we can use most in action buttons per screen. – Musfiq Shanta May 25 '22 at 03:00
38

You can use the flutter_speed_dial package: https://pub.dartlang.org/packages/flutter_speed_dial

On the link above have a example showing how to use it. You must use SpeedDial class and on children[] you can add some buttons with SpeedDialChild. The sample below shows 2 FABs.

Example using it:

Widget _getFAB() {
        return SpeedDial(
          animatedIcon: AnimatedIcons.menu_close,
          animatedIconTheme: IconThemeData(size: 22),
          backgroundColor: Color(0xFF801E48),
          visible: true,
          curve: Curves.bounceIn,
          children: [
                // FAB 1
                SpeedDialChild(
                child: Icon(Icons.assignment_turned_in),
                backgroundColor: Color(0xFF801E48),
                onTap: () { /* do anything */ },
                label: 'Button 1',
                labelStyle: TextStyle(
                    fontWeight: FontWeight.w500,
                    color: Colors.white,
                    fontSize: 16.0),
                labelBackgroundColor: Color(0xFF801E48)),
                // FAB 2
                SpeedDialChild(
                child: Icon(Icons.assignment_turned_in),
                backgroundColor: Color(0xFF801E48),
                onTap: () {
                   setState(() {
                      _counter = 0;
                   });
                },
                label: 'Button 2',
                labelStyle: TextStyle(
                    fontWeight: FontWeight.w500,
                    color: Colors.white,
                    fontSize: 16.0),
                labelBackgroundColor: Color(0xFF801E48))
          ],
        );
  }

Result:

enter image description here

Augusto
  • 3,825
  • 9
  • 45
  • 93
  • Thank you so much. Can you help me what to write in " onTap: () {}, label: 'Button 2'," to reset the counter? – fluttertalk Mar 14 '19 at 16:48
  • 4
    is it possible to have 2 FABs horizontally aligned in the bottom right of the screen without having the unfolding functionality of the speed dial widget? (i.e. so that both FABs are displayed permanently) – Rich Steinmetz Sep 20 '19 at 18:58
  • 1
    @Augusto your answer is correct, there is a syntax error. Just add ); to close the setState correctly. – Muhammad Sarmad Mahmood Malik Dec 24 '19 at 10:50
  • @Rich Steinmetz, look up the answer by RaZzLe and try with Row instead of Column – Dalibor Sep 15 '22 at 17:00
  • 1
    perfect simple example, better then the one they have in their pub.dev site, just one note: add this `_getFAB()` result to the `Scaffold`'s `floatingActionButton` attribute, like this: `floatingActionButton: _getFAB(),` – Shaybc Oct 08 '22 at 11:41
7

Yes, It's worked..!

      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: [
          FloatingActionButton(
            onPressed: () => {},
            child: Icon(Icons.navigate_before_rounded),
            heroTag: "fab1",
          ),
          FloatingActionButton(
            onPressed: () => {},
            child: Icon(Icons.navigate_next_rounded),
            heroTag: "fab2",
          ),
        ]
      )

two FloatingActionButton at bottom-right

Sachin Chillal
  • 393
  • 4
  • 6
6

According to medium post

You can use Column (for vertical alignment) or Row widget (for horizontal alignment) with 2 FAB as children and just set hero Tag null or assign diffent HeroTags.

Ko Lynn
  • 134
  • 4
  • 8
6

You can make it by setup "heroTag: null" as below:

Stack(
  children: <Widget>[
    Align(
      alignment: Alignment.bottomLeft,
      child: FloatingActionButton(
                heroTag: null,
             ...),
    ),
    Align(
      alignment: Alignment.bottomRight,
      child: FloatingActionButton(
                heroTag: null,
             ...),
    ),
  ],
)
Naimish Vinchhi
  • 775
  • 8
  • 12
1

I fixed it with this, also to add space between the buttons you can add a width and the 'hero' tags are very important.

floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
        floatingActionButton: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              FloatingActionButton(
                backgroundColor: Colors.green,
                heroTag: "btn",
                onPressed: () => _speak(textEditingController.text),
                child: Icon(Icons.play_arrow),
              ),
              SizedBox(
                width: 40,
              ),
              FloatingActionButton(
                backgroundColor: Colors.red,
                heroTag: "btn2",
                onPressed: () => _stop(),
                child: Icon(Icons.stop),
              )
            ],
          ),
        )

enter image description here

Daniel Salas DG
  • 69
  • 1
  • 11
0

In Flutter Documentation, we can use at most one floating action button on a single screen. We can do it using RawMaterialButton() widget. This widget parent widget of the floating action button

It's something like that

  class RoundIconButton extends StatelessWidget {
      const RoundIconButton({Key? key}) : super(key: key);

      @override
      Widget build(BuildContext context) {
        return RawMaterialButton(
          constraints: BoxConstraints(minHeight: 40, minWidth: 40),
          shape: CircleBorder(),
          fillColor: Colors.white,
          onPressed: () {},
          child: Text("+"),
        );
      }
    }
class Fab extends StatelessWidget {
  const Fab({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        RawMaterialButton(),
        RawMaterialButton(),
      ],
    );
  }
}
Musfiq Shanta
  • 1,298
  • 13
  • 9