diff --git a/example/lib/main.dart b/example/lib/main.dart index 0dc8c9f..bc2ee34 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -97,15 +97,11 @@ class _MyHomePageState extends State with TickerProviderStateMixin { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text("SpeedDial Location", - style: Theme.of(context).textTheme.bodyText1), + Text("SpeedDial Location", style: Theme.of(context).textTheme.bodyLarge), const SizedBox(height: 10), Container( decoration: BoxDecoration( - color: Theme.of(context).brightness == - Brightness.dark - ? Colors.grey[800] - : Colors.grey[200], + color: Theme.of(context).brightness == Brightness.dark ? Colors.grey[800] : Colors.grey[200], borderRadius: BorderRadius.circular(10)), child: DropdownButton( value: selectedfABLocation, @@ -113,25 +109,20 @@ class _MyHomePageState extends State with TickerProviderStateMixin { icon: const Icon(Icons.arrow_drop_down), iconSize: 20, underline: const SizedBox(), - onChanged: (fABLocation) => setState( - () => selectedfABLocation = fABLocation!), + onChanged: (fABLocation) => setState(() => selectedfABLocation = fABLocation!), selectedItemBuilder: (BuildContext context) { return items.map((item) { return Align( alignment: Alignment.centerLeft, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 4, horizontal: 10), - child: Text(item.value))); + child: Container(padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 10), child: Text(item.value))); }).toList(); }, items: items.map((item) { - return DropdownMenuItem< - FloatingActionButtonLocation>( + return DropdownMenuItem( + value: item, child: Text( item.value, ), - value: item, ); }).toList(), ), @@ -146,15 +137,11 @@ class _MyHomePageState extends State with TickerProviderStateMixin { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text("SpeedDial Direction", - style: Theme.of(context).textTheme.bodyText1), + Text("SpeedDial Direction", style: Theme.of(context).textTheme.bodyLarge), const SizedBox(height: 10), Container( decoration: BoxDecoration( - color: Theme.of(context).brightness == - Brightness.dark - ? Colors.grey[800] - : Colors.grey[200], + color: Theme.of(context).brightness == Brightness.dark ? Colors.grey[800] : Colors.grey[200], borderRadius: BorderRadius.circular(10)), child: DropdownButton( value: speedDialDirection, @@ -165,45 +152,28 @@ class _MyHomePageState extends State with TickerProviderStateMixin { onChanged: (sdo) { setState(() { speedDialDirection = sdo!; - selectedfABLocation = (sdo.isUp && - selectedfABLocation.value - .contains("Top")) || - (sdo.isLeft && - selectedfABLocation.value - .contains("start")) + selectedfABLocation = (sdo.isUp && selectedfABLocation.value.contains("Top")) || + (sdo.isLeft && selectedfABLocation.value.contains("start")) ? FloatingActionButtonLocation.endDocked - : sdo.isDown && - !selectedfABLocation.value - .contains("Top") + : sdo.isDown && !selectedfABLocation.value.contains("Top") ? FloatingActionButtonLocation.endTop - : sdo.isRight && - selectedfABLocation.value - .contains("end") - ? FloatingActionButtonLocation - .startDocked + : sdo.isRight && selectedfABLocation.value.contains("end") + ? FloatingActionButtonLocation.startDocked : selectedfABLocation; }); }, selectedItemBuilder: (BuildContext context) { - return SpeedDialDirection.values - .toList() - .map((item) { + return SpeedDialDirection.values.toList().map((item) { return Container( - padding: const EdgeInsets.symmetric( - vertical: 4, horizontal: 10), - child: Align( - alignment: Alignment.centerLeft, - child: Text( - describeEnum(item).toUpperCase())), + padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 10), + child: Align(alignment: Alignment.centerLeft, child: Text(describeEnum(item).toUpperCase())), ); }).toList(); }, - items: SpeedDialDirection.values - .toList() - .map((item) { + items: SpeedDialDirection.values.toList().map((item) { return DropdownMenuItem( - child: Text(describeEnum(item).toUpperCase()), value: item, + child: Text(describeEnum(item).toUpperCase()), ); }).toList(), ), @@ -320,21 +290,12 @@ class _MyHomePageState extends State with TickerProviderStateMixin { setState(() { switchLabelPosition = val; if (val) { - if ((selectedfABLocation.value.contains("end") || - selectedfABLocation.value - .toLowerCase() - .contains("top")) && + if ((selectedfABLocation.value.contains("end") || selectedfABLocation.value.toLowerCase().contains("top")) && speedDialDirection.isUp) { - selectedfABLocation = - FloatingActionButtonLocation.startDocked; - } else if ((selectedfABLocation.value - .contains("end") || - !selectedfABLocation.value - .toLowerCase() - .contains("top")) && + selectedfABLocation = FloatingActionButtonLocation.startDocked; + } else if ((selectedfABLocation.value.contains("end") || !selectedfABLocation.value.toLowerCase().contains("top")) && speedDialDirection.isDown) { - selectedfABLocation = - FloatingActionButtonLocation.startTop; + selectedfABLocation = FloatingActionButtonLocation.startTop; } } }); @@ -369,15 +330,13 @@ class _MyHomePageState extends State with TickerProviderStateMixin { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text("Navigation", - style: Theme.of(context).textTheme.bodyText1), + Text("Navigation", style: Theme.of(context).textTheme.bodyLarge), const SizedBox(height: 10), ElevatedButton( onPressed: () { Navigator.of(context).push( MaterialPageRoute( - builder: (_) => - MyHomePage(theme: widget.theme), + builder: (_) => MyHomePage(theme: widget.theme), ), ); }, @@ -409,8 +368,7 @@ class _MyHomePageState extends State with TickerProviderStateMixin { onPressed: toggleChildren, style: ElevatedButton.styleFrom( backgroundColor: Colors.blue[900], - padding: const EdgeInsets.symmetric( - horizontal: 22, vertical: 18), + padding: const EdgeInsets.symmetric(horizontal: 22, vertical: 18), ), child: const Text( "Custom Dial Root", @@ -419,12 +377,9 @@ class _MyHomePageState extends State with TickerProviderStateMixin { ); } : null, - buttonSize: - buttonSize, // it's the SpeedDial size which defaults to 56 itself + buttonSize: buttonSize, // it's the SpeedDial size which defaults to 56 itself // iconTheme: IconThemeData(size: 22), - label: extend - ? const Text("Open") - : null, // The label of the main button. + label: extend ? const Text("Open") : null, // The label of the main button. /// The active label of the main button, Defaults to label if not specified. activeLabel: extend ? const Text("Close") : null, @@ -455,9 +410,7 @@ class _MyHomePageState extends State with TickerProviderStateMixin { elevation: 8.0, animationCurve: Curves.elasticInOut, isOpenOnStart: false, - shape: customDialRoot - ? const RoundedRectangleBorder() - : const StadiumBorder(), + shape: customDialRoot ? const RoundedRectangleBorder() : const StadiumBorder(), // childMargin: EdgeInsets.symmetric(horizontal: 10, vertical: 5), children: [ SpeedDialChild( @@ -481,8 +434,7 @@ class _MyHomePageState extends State with TickerProviderStateMixin { foregroundColor: Colors.white, label: 'Show Snackbar', visible: true, - onTap: () => ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text(("Third Child Pressed")))), + onTap: () => ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text(("Third Child Pressed")))), onLongPress: () => debugPrint('THIRD CHILD LONG PRESS'), ), ], @@ -491,8 +443,7 @@ class _MyHomePageState extends State with TickerProviderStateMixin { shape: const CircularNotchedRectangle(), notchMargin: 8.0, child: Row( - mainAxisAlignment: selectedfABLocation == - FloatingActionButtonLocation.startDocked + mainAxisAlignment: selectedfABLocation == FloatingActionButtonLocation.startDocked ? MainAxisAlignment.end : selectedfABLocation == FloatingActionButtonLocation.endDocked ? MainAxisAlignment.start @@ -502,17 +453,13 @@ class _MyHomePageState extends State with TickerProviderStateMixin { IconButton( icon: const Icon(Icons.nightlight_round), tooltip: "Switch Theme", - onPressed: () => { - widget.theme.value = widget.theme.value.index == 2 - ? ThemeMode.light - : ThemeMode.dark - }, + onPressed: () => {widget.theme.value = widget.theme.value.index == 2 ? ThemeMode.light : ThemeMode.dark}, ), ValueListenableBuilder( valueListenable: isDialOpen, builder: (ctx, value, _) => IconButton( icon: const Icon(Icons.open_in_browser), - tooltip: (!value ? "Open" : "Close") + " Speed Dial", + tooltip: (!value ? "Open" : "Close") + (" Speed Dial"), onPressed: () => {isDialOpen.value = !isDialOpen.value}, )) ], diff --git a/lib/src/speed_dial.dart b/lib/src/speed_dial.dart index 3286a9a..137e2ee 100644 --- a/lib/src/speed_dial.dart +++ b/lib/src/speed_dial.dart @@ -10,8 +10,7 @@ import 'background_overlay.dart'; import 'speed_dial_child.dart'; import 'speed_dial_direction.dart'; -typedef AsyncChildrenBuilder = Future> Function( - BuildContext context); +typedef AsyncChildrenBuilder = Future> Function(BuildContext context); /// Builds the Speed Dial class SpeedDial extends StatefulWidget { @@ -150,8 +149,7 @@ class SpeedDial extends StatefulWidget { /// ignore backgroundColor, foregroundColor or any other property /// that was specific to FAB before like onPress, you will have to provide /// it again to your dialRoot button. - final Widget Function( - BuildContext context, bool open, VoidCallback toggleChildren)? dialRoot; + final Widget Function(BuildContext context, bool open, VoidCallback toggleChildren)? dialRoot; /// This is the child of the FAB, if specified it will ignore icon, activeIcon. final Widget? child; @@ -224,8 +222,7 @@ class SpeedDial extends StatefulWidget { State createState() => _SpeedDialState(); } -class _SpeedDialState extends State - with SingleTickerProviderStateMixin { +class _SpeedDialState extends State with SingleTickerProviderStateMixin { late final AnimationController _controller = AnimationController( duration: widget.animationDuration, vsync: this, @@ -274,8 +271,7 @@ class _SpeedDialState extends State void _checkChildren() { if (widget.children.length > 5) { - debugPrint( - 'Warning ! You are using more than 5 children, which is not compliant with Material design specs.'); + debugPrint('Warning ! You are using more than 5 children, which is not compliant with Material design specs.'); } } @@ -311,9 +307,7 @@ class _SpeedDialState extends State if (_open) { _controller.reverse().whenComplete(() { overlayEntry?.remove(); - if (widget.renderOverlay && - backgroundOverlay != null && - backgroundOverlay!.mounted) { + if (widget.renderOverlay && backgroundOverlay != null && backgroundOverlay!.mounted) { backgroundOverlay?.remove(); } }); @@ -346,8 +340,7 @@ class _SpeedDialState extends State onTap: _toggleChildren, // (_open && !widget.closeManually) ? _toggleChildren : null, animation: _controller, - color: widget.overlayColor ?? - (dark ? Colors.grey[900] : Colors.white)!, + color: widget.overlayColor ?? (dark ? Colors.grey[900] : Colors.white)!, opacity: widget.overlayOpacity, ); }, @@ -357,8 +350,8 @@ class _SpeedDialState extends State if (!mounted) return; _controller.forward(); - if (widget.renderOverlay) Overlay.of(context)!.insert(backgroundOverlay!); - Overlay.of(context)!.insert(overlayEntry!); + if (widget.renderOverlay) Overlay.of(context).insert(backgroundOverlay!); + Overlay.of(context).insert(overlayEntry!); } if (!mounted) return; @@ -386,18 +379,14 @@ class _SpeedDialState extends State : AnimatedBuilder( animation: _controller, builder: (BuildContext context, _) => Transform.rotate( - angle: - (widget.activeChild != null || widget.activeIcon != null) && - widget.useRotationAnimation - ? _controller.value * widget.animationAngle - : 0, + angle: (widget.activeChild != null || widget.activeIcon != null) && widget.useRotationAnimation + ? _controller.value * widget.animationAngle + : 0, child: AnimatedSwitcher( duration: widget.animationDuration, child: (widget.child != null && _controller.value < 0.4) ? widget.child - : (widget.activeIcon == null && - widget.activeChild == null || - _controller.value < 0.4) + : (widget.activeIcon == null && widget.activeChild == null || _controller.value < 0.4) ? Container( decoration: BoxDecoration( shape: widget.gradientBoxShape, @@ -415,8 +404,7 @@ class _SpeedDialState extends State ), ) : Transform.rotate( - angle: - widget.useRotationAnimation ? -pi * 1 / 2 : 0, + angle: widget.useRotationAnimation ? -pi * 1 / 2 : 0, child: widget.activeChild ?? Container( decoration: BoxDecoration( @@ -443,17 +431,11 @@ class _SpeedDialState extends State opacity: animation, child: child, ), - child: (!_open || widget.activeLabel == null) - ? widget.label - : widget.activeLabel, + child: (!_open || widget.activeLabel == null) ? widget.label : widget.activeLabel, ); - final backgroundColorTween = ColorTween( - begin: widget.backgroundColor, - end: widget.activeBackgroundColor ?? widget.backgroundColor); - final foregroundColorTween = ColorTween( - begin: widget.foregroundColor, - end: widget.activeForegroundColor ?? widget.foregroundColor); + final backgroundColorTween = ColorTween(begin: widget.backgroundColor, end: widget.activeBackgroundColor ?? widget.backgroundColor); + final foregroundColorTween = ColorTween(begin: widget.foregroundColor, end: widget.activeForegroundColor ?? widget.foregroundColor); var animatedFloatingButton = AnimatedBuilder( animation: _controller, @@ -464,20 +446,12 @@ class _SpeedDialState extends State visible: widget.visible, tooltip: widget.tooltip, mini: widget.mini, - dialRoot: widget.dialRoot != null - ? widget.dialRoot!(context, _open, _toggleChildren) - : null, - backgroundColor: widget.backgroundColor != null - ? backgroundColorTween.lerp(_controller.value) - : null, - foregroundColor: widget.foregroundColor != null - ? foregroundColorTween.lerp(_controller.value) - : null, + dialRoot: widget.dialRoot != null ? widget.dialRoot!(context, _open, _toggleChildren) : null, + backgroundColor: widget.backgroundColor != null ? backgroundColorTween.lerp(_controller.value) : null, + foregroundColor: widget.foregroundColor != null ? foregroundColorTween.lerp(_controller.value) : null, elevation: widget.elevation, onLongPress: _toggleChildren, - callback: (_open || widget.onPress == null) - ? _toggleChildren - : widget.onPress, + callback: (_open || widget.onPress == null) ? _toggleChildren : widget.onPress, size: widget.buttonSize, label: widget.label != null ? label : null, heroTag: widget.heroTag, @@ -568,9 +542,7 @@ class _ChildrensOverlay extends StatelessWidget { if (!widget.closeManually) toggleChildren(); }, shape: child.shape, - heroTag: widget.heroTag != null - ? '${widget.heroTag}-child-$index' - : null, + heroTag: widget.heroTag != null ? '${widget.heroTag}-child-$index' : null, childMargin: widget.childMargin, childPadding: widget.childPadding, child: child.child, @@ -603,30 +575,18 @@ class _ChildrensOverlay extends StatelessWidget { : Alignment.center, offset: widget.direction.isDown ? Offset( - (widget.switchLabelPosition || - dialKey.globalPaintBounds == null - ? 0 - : dialKey.globalPaintBounds!.size.width) + + (widget.switchLabelPosition || dialKey.globalPaintBounds == null ? 0 : dialKey.globalPaintBounds!.size.width) + max(widget.childrenButtonSize.height - 56, 0) / 2, dialKey.globalPaintBounds!.size.height) : widget.direction.isUp ? Offset( - (widget.switchLabelPosition || - dialKey.globalPaintBounds == null - ? 0 - : dialKey.globalPaintBounds!.size.width) + + (widget.switchLabelPosition || dialKey.globalPaintBounds == null ? 0 : dialKey.globalPaintBounds!.size.width) + max(widget.childrenButtonSize.width - 56, 0) / 2, 0) : widget.direction.isLeft - ? Offset( - -10.0, - dialKey.globalPaintBounds == null - ? 0 - : dialKey.globalPaintBounds!.size.height / 2) - : widget.direction.isRight && - dialKey.globalPaintBounds != null - ? Offset(dialKey.globalPaintBounds!.size.width + 12, - dialKey.globalPaintBounds!.size.height / 2) + ? Offset(-10.0, dialKey.globalPaintBounds == null ? 0 : dialKey.globalPaintBounds!.size.height / 2) + : widget.direction.isRight && dialKey.globalPaintBounds != null + ? Offset(dialKey.globalPaintBounds!.size.width + 12, dialKey.globalPaintBounds!.size.height / 2) : const Offset(-10.0, 0.0), link: layerLink, showWhenUnlinked: false, @@ -634,9 +594,7 @@ class _ChildrensOverlay extends StatelessWidget { type: MaterialType.transparency, child: Container( padding: EdgeInsets.symmetric( - horizontal: widget.direction.isUp || widget.direction.isDown - ? max(widget.buttonSize.width - 56, 0) / 2 - : 0, + horizontal: widget.direction.isUp || widget.direction.isDown ? max(widget.buttonSize.width - 56, 0) / 2 : 0, ), margin: widget.spacing != null ? EdgeInsets.fromLTRB( @@ -648,13 +606,9 @@ class _ChildrensOverlay extends StatelessWidget { : null, child: _buildColumnOrRow( widget.direction.isUp || widget.direction.isDown, - crossAxisAlignment: widget.switchLabelPosition - ? CrossAxisAlignment.start - : CrossAxisAlignment.end, + crossAxisAlignment: widget.switchLabelPosition ? CrossAxisAlignment.start : CrossAxisAlignment.end, mainAxisSize: MainAxisSize.min, - children: widget.direction.isDown || widget.direction.isRight - ? _getChildrenList().reversed.toList() - : _getChildrenList(), + children: widget.direction.isDown || widget.direction.isRight ? _getChildrenList().reversed.toList() : _getChildrenList(), ), ), ), @@ -665,10 +619,7 @@ class _ChildrensOverlay extends StatelessWidget { } Widget _buildColumnOrRow(bool isColumn, - {CrossAxisAlignment? crossAxisAlignment, - MainAxisAlignment? mainAxisAlignment, - required List children, - MainAxisSize? mainAxisSize}) { + {CrossAxisAlignment? crossAxisAlignment, MainAxisAlignment? mainAxisAlignment, required List children, MainAxisSize? mainAxisSize}) { return isColumn ? Column( mainAxisSize: mainAxisSize ?? MainAxisSize.max,