2

I'm using UnicornDialer from the unicorndial package to create a Material speed dial experience on the home page of my app, but if I set the shape property to define a notch, then notch is not painted correctly:

enter image description here

I noticed on another package (flutter_speed_dial) that this was explicitly mentioned as not working:

The SpeedDial widget is built to be placed in the floatingActionButton parameter of the Scaffold widget. It's not possible to set its position with the Scaffold.floatingActionButtonLocation parameter though. The use with the Scaffold.bottomNavigationBar is possible but the floating button will be placed above the bar, without the possibility to be placed with a notch.

In the case of UnicornDialer the widget returned by the build method is a standard FloatingActionButton and having trawled through the code for Scaffold and BottomAppBar I can't work out why the notch is corrupted like that.

I had tried using a standard FAB (but transparent) to create the notch, then wrapping the Scaffold and UnicornDialer in a Stack to position everything, which worked fine, but then when you show a SnackBar the UnicornDialer doesn't move, so I'm back to needing BottomAppBar to treat the custom FAB properly for notch calculation. Any ideas?

Derek Lakin
  • 16,179
  • 36
  • 51
  • I posted earlier answer which suggested the negative notch margin but quickly realized that I did indirectly deleted the notch so I deleted the previous answer but this current answer is actually working fine. hope that help. – Saed Nabil Dec 11 '18 at 10:58

1 Answers1

1

You need to wrap UnicornDialer by a container and control the notch margin , please note that notchMargin can take negative value,

it seems that the renderer of the notch of the bottomAppBar are not able to calculate the Besier curves correctly from the raw UnicornDialer .

you can use the following code as a guide. it is working well

import 'package:flutter/material.dart';
import 'package:unicorndial/unicorndial.dart';

void main() =>
    runApp(new MaterialApp(debugShowCheckedModeBanner: false, home: Example()));

class Example extends StatefulWidget {
  _Example createState() => _Example();
}

class _Example extends State<Example> {
  @override
  Widget build(BuildContext context) {
    var childButtons = List<UnicornButton>();

    childButtons.add(UnicornButton(
        hasLabel: true,
        labelText: "Choo choo",
        currentButton: FloatingActionButton(

          heroTag: "train",
          backgroundColor: Colors.redAccent,
          mini: true,
          child: Icon(Icons.train),
          onPressed: () {},
        )));

    childButtons.add(UnicornButton(
        currentButton: FloatingActionButton(
            heroTag: "airplane",
            backgroundColor: Colors.greenAccent,
            mini: true,
            child: Icon(Icons.airplanemode_active))));

    childButtons.add(UnicornButton(
        currentButton: FloatingActionButton(
            heroTag: "directions",
            backgroundColor: Colors.blueAccent,
            mini: true,
            child: Icon(Icons.directions_car))));

    return Scaffold(

      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      bottomNavigationBar: new BottomAppBar(
        shape: CircularNotchedRectangle(),


        notchMargin: -10.0,

        color: Colors.blue,
        child: new Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            IconButton(
              icon: Icon(Icons.menu),
              onPressed: () {},
            ),
            IconButton(
              icon: Icon(Icons.search),
              onPressed: () {},
            ),
          ],
        ),
      ),
      //floatingActionButton: FloatingActionButton(onPressed: (){}),
      floatingActionButton: Container(
        width: 100.0,
        height: 100.0,
        child: UnicornDialer(
            hasNotch: true,
            //hasBackground: false,
            backgroundColor: Color.fromRGBO(255, 255, 255, 0.0),
            parentButtonBackground: Colors.redAccent,
            orientation: UnicornOrientation.VERTICAL,
            parentButton: Icon(Icons.add),
            childButtons: childButtons),
      ),
      appBar: AppBar(),
      body: Container(

        child: Center(
          child: RaisedButton(
            onPressed: () {
              setState(() {});
            },
          ),
        ),
      ),
    );
  }
}
Saed Nabil
  • 6,705
  • 1
  • 14
  • 36
  • Yes, that seems to work, though setting the size of the Container affects the size of the FAB. Do you know what the size *should* be to meet the Material guidelines (56dp)? – Derek Lakin Dec 12 '18 at 14:16
  • min width 56dp min hight 112dp ,above these thresholds will only affect the notch not the fab – Saed Nabil Dec 12 '18 at 14:45
  • after more investigation the correct min width should be 56dp and the min hight should be 56*1.5 i.e 84dp – Saed Nabil Dec 12 '18 at 16:59
  • Thanks. Where does the 1.5 multiplier come from? If it's a circular FAB, why is the min height greater than the min width? – Derek Lakin Dec 13 '18 at 16:29
  • this "multiplier" is only needed in case the main fab has children, if not it will be 56dp each but adding children to the main fab will add internal cross axis padding which hard to track but I figured out it is around 28dp in total. – Saed Nabil Dec 13 '18 at 17:45
  • When I wrap the UnicornDialer with suggested Container, it resolves the layout issue but I lose the OnPressed action of the child buttons. – CoastalB Aug 13 '19 at 07:28