FloatingActionButton Create a Speed Dial widget

I went through 2 kinds of FloatingActionButtons and disclosed how to situate them on a page. As guaranteed in this post I’m demonstrating how to make a supposed Speed Dial gadget utilizing FABs and movement. It’s very simple to do. I will tell you bit by bit the best way to accomplish this.

To have the option to re-utilize our Speed Dial gadget and don’t dirty our page we ought to make a StatefulWidget. I have clarified Stateless and StatefulWidgets in one of my past posts. Yet, to recap, we need a StatefulWidget, on the grounds that we need to change our state. For this situation, we need to show and shroud FABs and monitor our movement.

Our StatefulWidget needs to utilize SingleTickerProviderStateMixin to be told about activity outlines.

class AnimatedFab extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => AnimatedFabState();
}

class AnimatedFabState extends State<AnimatedFab>
    with SingleTickerProviderStateMixin {

  @override
  void initState() {
    // We will initialize our animation here
    super.initState();
  }

  @override
  void dispose() {
    // Here we will dispose of our AnimationController
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // This is where our FABs will be rendered
    return null;
  }

}
  • Since we have our StatefulWidget prepared, we will begin characterizing our liveliness and our FABs. We need the accompanying things to arrangement:
  • AnimationController: as the name says, to control our activity
  • Animation: this is required on the off chance that we need to invigorate the shade of the FAB as well
  • Animation: this is the advancement expected to quicken the symbol. This is helpful to vitalize symbol and change it when our Speed Dial menu is open.
  • Bend: we need this class to characterize how our movement changes over the long haul
  • isOpened: a banner to monitor whether our menu is open
import 'dart:async';

import 'package:flutter/material.dart';

void main() {
  runApp(App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Show Hide Widget - exerror',
      home: Scaffold(
        appBar: AppBar(
          title: Text("FloatingActionBar - exerror.com"),
        ),
        body: Container(),
        floatingActionButton: AnimatedFab(),
      ),
      debugShowCheckedModeBanner: false,
    );
  }
}

class AnimatedFab extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => AnimatedFabState();
}

class AnimatedFabState extends State<AnimatedFab>
    with SingleTickerProviderStateMixin {
  bool isOpened = false;
  AnimationController _animationController;
  Animation<Color> _animateColor;
  Animation<double> _animateIcon;
  Curve _curve = Curves.easeOut;

  @override
  void initState() {
    _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 500))
          ..addListener(() {
            setState(() {});
          });
    _animateIcon =
        Tween<double>(begin: 0.0, end: 1.0).animate(_animationController);
    _animateColor = ColorTween(
      begin: Colors.blue,
      end: Colors.lightBlue,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Interval(
        0.00,
        1.00,
        curve: _curve,
      ),
    ));
    super.initState();
  }

  void animate() {
    if (!isOpened) {
      _animationController.forward();
    } else {
      _animationController.reverse();
    }
    isOpened = !isOpened;
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      backgroundColor: _animateColor.value,
      onPressed: animate,
      tooltip: 'Open menu',
      child: AnimatedIcon(
        icon: AnimatedIcons.menu_close,
        progress: _animateIcon,
      ),
    );
  }
}

Notice that AnimatedIcon is a helpful gadget that works like a typical symbol, however shows the liveliness dependent on the advancement. The rundown of accessible energized symbols is sadly restricted. We should perceive what it looks like at this point.

FloatingActionButton Create a Speed Dial widget

The fundamental FAB is presently pleasantly enlivened. What we need to do now is to add our menu things (other FABs and as per Google you ought not add more than 6 of them, 7 including the menu FAB itself).

We will utilize interpretation to open the menu upwards and remember the distance between the symbols. So let roll out certain improvements to the code.

import 'dart:async';

import 'package:flutter/material.dart';

void main() {
  runApp(App());
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Show Hide Widget - exerror',
      home: Scaffold(
        appBar: AppBar(
          title: Text("FloatingActionBar - exerror.com"),
        ),
        body: Container(),
        floatingActionButton: SpeedDial(),
      ),
      debugShowCheckedModeBanner: false,
    );
  }
}

class SpeedDial extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => SpeedDialState();
}

class SpeedDialState extends State<SpeedDial>
    with SingleTickerProviderStateMixin {
  bool _isOpened = false;
  AnimationController _animationController;
  Animation<Color> _buttonColor;
  Animation<double> _animateIcon;
  Animation<double> _translateButton;
  Curve _curve = Curves.easeOut;
  // this is needed to know how much to "translate"
  double _fabHeight = 56.0;
  // when the menu is closed, we remove elevation to prevent
  // stacking all elevations
  bool _shouldHaveElevation = false;

  @override
  initState() {
    // a bit faster animation, which looks better: 300
    _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 300))
          ..addListener(() {
            setState(() {});
          });
    _animateIcon =
        Tween<double>(begin: 0.0, end: 1.0).animate(_animationController);
    _buttonColor = ColorTween(
      begin: Colors.blue,
      end: Colors.red,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Interval(
        0.00,
        1.00,
        curve: Curves.linear,
      ),
    ));

    // this does the translation of menu items
    _translateButton = Tween<double>(
      begin: _fabHeight,
      end: -14.0,
    ).animate(CurvedAnimation(
      parent: _animationController,
      curve: Interval(
        0.0,
        0.75,
        curve: _curve,
      ),
    ));
    super.initState();
  }

  void animate() {
    if (!_isOpened) {
      _animationController.forward();
    } else {
      _animationController.reverse();
    }
    _isOpened = !_isOpened;
    // here we update whether or not they FABs should have elevation
    _shouldHaveElevation = !_shouldHaveElevation;
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  Widget composeButton() {
    return Container(
      child: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Compose',
        child: Icon(Icons.email),
        elevation: _shouldHaveElevation ? 6.0 : 0,
      ),
    );
  }

  Widget copyButton() {
    return Container(
      child: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Copy',
        child: Icon(Icons.content_copy),
        elevation: _shouldHaveElevation ? 6.0 : 0,
      ),
    );
  }

  Widget shareButton() {
    return Container(
      child: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Share',
        child: Icon(Icons.share),
        elevation: _shouldHaveElevation ? 6.0 : 0,
      ),
    );
  }

  Widget menuButton() {
    return Container(
      child: FloatingActionButton(
        backgroundColor: _buttonColor.value,
        onPressed: animate,
        tooltip: 'Toggle menu',
        child: AnimatedIcon(
          icon: AnimatedIcons.menu_close,
          progress: _animateIcon,
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.end,
      children: <Widget>[
        Transform(
          transform: Matrix4.translationValues(
            0.0,
            _translateButton.value * 3.0,
            0.0,
          ),
          child: composeButton(),
        ),
        Transform(
          transform: Matrix4.translationValues(
            0.0,
            _translateButton.value * 2.0,
            0.0,
          ),
          child: copyButton(),
        ),
        Transform(
          transform: Matrix4.translationValues(
            0.0,
            _translateButton.value,
            0.0,
          ),
          child: shareButton(),
        ),
        menuButton(),
      ],
    );
  }
}

Which looks now like this:

FloatingActionButton Create a Speed Dial widget

It is ideal to make the gadget totally re-usable by adding params to it. For instance, it is ideal to have the option to characterize what menu things we need to add to the Speed Dial menu as opposed to having them hard-coded. It would, nonetheless, be a superior thought on the off chance that I clarify that later as a different subject.

Summery

So it’s all About All possible solutions. Hope this above all solution helped you a lot. Comment below Your thoughts and your queries. Comment Below on your suggestion.

Check Out Below Article

TypeError: this.getOptions is not a function in vue.js

Leave a Comment

x