import 'package:flutter/material.dart'; // https://stackoverflow.com/questions/46480221/flutter-floating-action-button-with-speed-dail class FabWithIcons extends StatefulWidget { FabWithIcons({super.key, required this.icons, required this.onIconTapped}); final List icons; ValueChanged onIconTapped; @override State createState() => FabWithIconsState(); } class FabWithIconsState extends State with TickerProviderStateMixin { late AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 250), ); } @override Widget build(BuildContext context) { return Column( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: List.generate(widget.icons.length, (int index) { return _buildChild(index); }).toList() ..add( _buildFab(), ), ); } Widget _buildChild(int index) { Color backgroundColor = Theme.of(context).cardColor; Color foregroundColor = Theme.of(context).secondaryHeaderColor; return Container( height: 70.0, width: 56.0, alignment: FractionalOffset.topCenter, child: ScaleTransition( scale: CurvedAnimation( parent: _controller, curve: Interval(0.0, 1.0 - index / widget.icons.length / 2.0, curve: Curves.easeOut), ), child: FloatingActionButton( backgroundColor: backgroundColor, mini: true, child: Icon(widget.icons[index], color: foregroundColor), onPressed: () => _onTapped(index), ), ), ); } Widget _buildFab() { return FloatingActionButton( onPressed: () { if (_controller.isDismissed) { _controller.forward(); } else { _controller.reverse(); } }, tooltip: 'Increment', elevation: 2.0, child: const Icon(Icons.add), ); } void _onTapped(int index) { _controller.reverse(); widget.onIconTapped(index); } }