2

I am adding animated icons in my floating action button at bottom navigation bar. But after adding 2 buttons my FAB moved down.

I am using following code

Widget _buildCenterTab(){
    return new Column(
      mainAxisSize: MainAxisSize.min,
      children: new List.generate(icons.length, (int index) {
        Widget child = new Container(
          height: 56.0,
          width: 56.0,
          alignment: FractionalOffset.topCenter,
          child: new ScaleTransition(
            scale: new CurvedAnimation(
              parent: _controller,
              curve: new Interval(
                  0.0,
                  1.0 - index / icons.length / 2.0,
                  curve: Curves.easeOut
              ),
            ),
            child: new FloatingActionButton(
              heroTag: null,
              backgroundColor: blueColor,
              mini: true,
              child: new Icon(icons[index], color: Colors.white),
              onPressed: () {},
            ),
          ),
        );
        return child;
      }).toList()..add(
        new FloatingActionButton(
          heroTag: null,
          child: new AnimatedBuilder(
            animation: _controller,
            builder: (BuildContext context, Widget child) {
              return new Transform(
                transform: new Matrix4.rotationZ(_controller.value * 0.5 * math.pi),
                alignment: FractionalOffset.center,
                child: new Icon(
                    _controller.isDismissed
                        ? Icons.add
                        : Icons.close),
              );
            },
          ),
          onPressed: () {
            if (_controller.isDismissed) {
              _controller.forward();
            } else {
              _controller.reverse();
            }
          },
        ),
      ),
    );
  }

Here is screenshot of my problem: enter image description here

Code Hunter
  • 10,075
  • 23
  • 72
  • 102

2 Answers2

3

One way to get around this would be to create your own FloatingActionButtonLocation

class _CustomCenterDockedFloatingActionButtonLocation extends FloatingActionButtonLocation {
  const _CustomCenterDockedFloatingActionButtonLocation();

  @override
  Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) {
    final double fabX = (scaffoldGeometry.scaffoldSize.width - scaffoldGeometry.floatingActionButtonSize.width) / 2.0;
    return Offset(fabX, getDockedY(scaffoldGeometry));
  }

  double getDockedY(ScaffoldPrelayoutGeometry scaffoldGeometry) {
    final double contentBottom = scaffoldGeometry.contentBottom;
    final double bottomSheetHeight = scaffoldGeometry.bottomSheetSize.height;
    final double fabHeight = scaffoldGeometry.floatingActionButtonSize.height;
    final double snackBarHeight = scaffoldGeometry.snackBarSize.height;

    double fabY = contentBottom - fabHeight / 2.0;
    // The FAB should sit with a margin between it and the snack bar.
    if (snackBarHeight > 0.0)
      fabY = math.min(fabY, contentBottom - snackBarHeight - fabHeight - kFloatingActionButtonMargin);
    // The FAB should sit with its center in front of the top of the bottom sheet.
    if (bottomSheetHeight > 0.0)
      fabY = math.min(fabY, contentBottom - bottomSheetHeight - fabHeight / 2.0);

    final double maxFabY = scaffoldGeometry.scaffoldSize.height - fabHeight;
    return math.min(maxFabY, fabY);
  }
}

This is using the same code as FloatingActionButtonLocation.centerDocked taken from the source and then you can use it in a Scaffold like so:

Scaffold(
    body: Container(),
    floatingActionButton: _buildCenterTab(),
    floatingActionButtonLocation: _CustomCenterDockedFloatingActionButtonLocation(),
    ...
);
Jordan Davies
  • 9,925
  • 6
  • 40
  • 51
  • I've copied this straight from the Flutter source code so it will work exactly the same as the current FloatingActionButtonLocation.centerDocked code, you'll need to have a play around with the code yourself to make it fit your needs. – Jordan Davies Jan 02 '19 at 11:01
  • The answer is gold. Thank you for this great contribution! – GhoSt Sep 09 '21 at 07:49
0

check this code you can wrap your entire column with a container and using transform property to shift it up by 56/2 to center dock it.

import 'dart:math' as math;
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
      home: HomeScreen(),
    );
  }
}


class HomeScreen extends StatefulWidget{
  @override
  HomeScreenState createState() {
    return new HomeScreenState();
  }
}

class HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin{
  List<IconData> icons = [(Icons.add),(Icons.clear),(Icons.forward)];
  AnimationController _controller ;
  @override
  void initState() {
    _controller = AnimationController(vsync: this,duration: Duration(seconds: 1));
    super.initState();
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      bottomNavigationBar: BottomNavigationBar(
        items: [
            BottomNavigationBarItem(
                icon: Icon(Icons.map),
                title: Text("Hi")),
            BottomNavigationBarItem(
              icon:Icon(Icons.image),
              title:Text("There"),
            )
          ]
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      floatingActionButton: Container(
        width: 56.0,
        height: 56.0*4,
        transform: Matrix4.translationValues(0, -56/2, 0),
        child: new Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.end,
          children: new List.generate(icons.length, (int index) {
            Widget child = new Container(
              height: 56.0,
              width: 56.0,
              alignment: FractionalOffset.topCenter,
              child: new ScaleTransition(
                scale: new CurvedAnimation(
                  parent: _controller,
                  curve: new Interval(
                      0.0,
                      1.0 - index / icons.length / 2.0,
                      curve: Curves.easeOut
                  ),
                ),
                child: new FloatingActionButton(
                  heroTag: null,
                  backgroundColor: Colors.blue,
                  mini: true,
                  child: new Icon(icons[index], color: Colors.white),
                  onPressed: () {},
                ),
              ),
            );
            return child;
          }).toList()..add(
            new FloatingActionButton(
              heroTag: null,
              child: new AnimatedBuilder(
                animation: _controller,
                builder: (BuildContext context, Widget child) {
                  return new Transform(
                    transform: new Matrix4.rotationZ(_controller.value * 0.5 * math.pi),
                    alignment: FractionalOffset.center,
                    child: new Icon(
                        _controller.isDismissed
                            ? Icons.add
                            : Icons.close),
                  );
                },
              ),
              onPressed: () {
                if (_controller.isDismissed) {
                  _controller.forward();
                } else {
                  _controller.reverse();
                }
              },
            ),
          ),
        ),
      ),
    );
  }
}
Saed Nabil
  • 6,705
  • 1
  • 14
  • 36
  • 1
    This also not helping me. It does only notch design change. – Code Hunter Jan 02 '19 at 12:03
  • if you want to implement this behavior you can check this question https://stackoverflow.com/questions/51894449/notch-in-bottomappbar-for-custom-fab/53722628#53722628 you can check this repository to get an idea how it is implemented https://github.com/tiagojencmartins/unicornspeeddial – Saed Nabil Jan 02 '19 at 16:07