diff --git a/lib/navigation_dot_bar.dart b/lib/navigation_dot_bar.dart index 292d97b..1c75693 100644 --- a/lib/navigation_dot_bar.dart +++ b/lib/navigation_dot_bar.dart @@ -5,10 +5,29 @@ import 'package:flutter/material.dart'; class BottomNavigationDotBar extends StatefulWidget{ final List items; - final Color activeColor; - final Color color; - - const BottomNavigationDotBar({@required this.items, this.activeColor, this.color, Key key}): super(key: key); + final Color? activeColor; + final Color? color; + final int initialPosition; + final double? elevation; + final BorderRadiusGeometry? border; + final EdgeInsetsGeometry? padding; + final int? animationSpeed; + final CircleAvatar? indicator; + final bool useThemeColors; + + const BottomNavigationDotBar({ + required this.items, + this.activeColor, + this.color, + this.initialPosition = 0, + this.elevation, + this.border, + this.padding, + this.animationSpeed, + this.indicator, + this.useThemeColors = false, + Key? key + }): super(key: key); @override State createState() => _BottomNavigationDotBarState(); @@ -18,31 +37,49 @@ class BottomNavigationDotBar extends StatefulWidget{ class _BottomNavigationDotBarState extends State{ GlobalKey _keyBottomBar = GlobalKey(); - double _numPositionBase, _numDifferenceBase, _positionLeftIndicatorDot; - int _indexPageSelected = 0; - Color _color, _activeColor; + double _numPositionBase = 0.0; + double _numDifferenceBase = 0.0; + double? _positionLeftIndicatorDot; + int _indexPageSelected = 1; + Color? _color; + Color? _activeColor; + + double? _elevation; + BorderRadiusGeometry? _border; + EdgeInsetsGeometry? _padding; + int? _animationSpeed; + CircleAvatar? _indicator; @override void initState() { - WidgetsBinding.instance.addPostFrameCallback(_afterLayout); + _elevation = widget.elevation ?? 5; + _border = widget.border ?? BorderRadius.circular(10); + _padding = widget.padding ?? EdgeInsets.fromLTRB(10, 0, 10, 5); + _animationSpeed = widget.animationSpeed ?? 400; + _indicator = widget.indicator ?? CircleAvatar(radius: 2.5, backgroundColor: widget.useThemeColors ? _activeColor : Colors.black); + WidgetsBinding.instance!.addPostFrameCallback(_afterLayout); super.initState(); } _afterLayout(_) { + _indexPageSelected = widget.initialPosition; _color = widget.color ?? Colors.black45; - _activeColor = widget.activeColor ?? Theme.of(context).primaryColor; - final sizeBottomBar = (_keyBottomBar.currentContext.findRenderObject() as RenderBox).size; + + final sizeBottomBar = (_keyBottomBar.currentContext!.findRenderObject() as RenderBox).size; _numPositionBase = ((sizeBottomBar.width / widget.items.length)); _numDifferenceBase = (_numPositionBase - (_numPositionBase / 2) + 2); - setState(() { _positionLeftIndicatorDot = _numPositionBase - _numDifferenceBase; }); + setState(() { + _activeColor = widget.activeColor ?? Theme.of(context).primaryColor; + _positionLeftIndicatorDot = (_numPositionBase * (_indexPageSelected+1))-_numDifferenceBase; + }); } @override Widget build(BuildContext context) => Container ( - padding: EdgeInsets.fromLTRB(5, 0, 5, 5), + padding: _padding, child: Material( - elevation: 5, - borderRadius: BorderRadius.circular(10), + elevation: _elevation!, + borderRadius: _border, child: Container( padding: EdgeInsets.symmetric(vertical: 12), child: Stack( @@ -56,8 +93,8 @@ class _BottomNavigationDotBarState extends State{ ), ), AnimatedPositioned( - child: CircleAvatar(radius: 2.5, backgroundColor: _activeColor), - duration: Duration(milliseconds: 400), + child: _indicator!, + duration: Duration(milliseconds: _animationSpeed!), curve: Curves.fastOutSlowIn, left: _positionLeftIndicatorDot, bottom: 0 @@ -69,7 +106,7 @@ class _BottomNavigationDotBarState extends State{ ); List<_NavigationIconButton> _createNavigationIconButtonList(Map mapItem){ - List<_NavigationIconButton> children = List<_NavigationIconButton>(); + List<_NavigationIconButton> children = []; mapItem.forEach((index, item) => children.add(_NavigationIconButton(item.icon, (index == _indexPageSelected) ? _activeColor : _color,item.onTap,() { _changeOptionBottomBar(index); })) ); @@ -78,7 +115,9 @@ class _BottomNavigationDotBarState extends State{ void _changeOptionBottomBar(int indexPageSelected){ if(indexPageSelected != _indexPageSelected){ - setState(() { _positionLeftIndicatorDot = (_numPositionBase * (indexPageSelected+1))-_numDifferenceBase; }); + setState(() { + _positionLeftIndicatorDot = (_numPositionBase * (indexPageSelected+1))-_numDifferenceBase; + }); _indexPageSelected = indexPageSelected; } } @@ -88,7 +127,7 @@ class _BottomNavigationDotBarState extends State{ class BottomNavigationDotBarItem{ final IconData icon; final NavigationIconButtonTapCallback onTap; - const BottomNavigationDotBarItem({@required this.icon, this.onTap}) : assert(icon != null); + const BottomNavigationDotBarItem({required this.icon, required this.onTap}) : assert(icon != null); } typedef NavigationIconButtonTapCallback = void Function(); @@ -96,11 +135,11 @@ typedef NavigationIconButtonTapCallback = void Function(); class _NavigationIconButton extends StatefulWidget { final IconData _icon; - final Color _colorIcon; + final Color? _colorIcon; final NavigationIconButtonTapCallback _onTapInternalButton; final NavigationIconButtonTapCallback _onTapExternalButton; - const _NavigationIconButton(this._icon, this._colorIcon, this._onTapInternalButton, this._onTapExternalButton, {Key key}): super(key: key); + const _NavigationIconButton(this._icon, this._colorIcon, this._onTapInternalButton, this._onTapExternalButton, {Key? key}): super(key: key); @override _NavigationIconButtonState createState() => _NavigationIconButtonState(); @@ -109,29 +148,29 @@ class _NavigationIconButton extends StatefulWidget { class _NavigationIconButtonState extends State<_NavigationIconButton> with SingleTickerProviderStateMixin { - AnimationController _controller; - Animation _scaleAnimation; + AnimationController? _controller; + Animation? _scaleAnimation; double _opacityIcon = 1; @override void initState() { super.initState(); _controller = AnimationController(vsync: this, duration: Duration(milliseconds: 200)); - _scaleAnimation = Tween(begin: 1, end: 0.93).animate(_controller); + _scaleAnimation = Tween(begin: 1, end: 0.93).animate(_controller!.view); } @override Widget build(BuildContext context) => GestureDetector( onTapDown: (_) { - _controller.forward(); + _controller!.forward(); setState(() { _opacityIcon = 0.7; }); }, onTapUp: (_) { - _controller.reverse(); + _controller!.reverse(); setState(() { _opacityIcon = 1; }); }, onTapCancel: () { - _controller.reverse(); + _controller!.reverse(); setState(() { _opacityIcon = 1; }); }, onTap: () { @@ -139,7 +178,7 @@ class _NavigationIconButtonState extends State<_NavigationIconButton> with Singl widget._onTapExternalButton(); }, child: ScaleTransition( - scale: _scaleAnimation, + scale: _scaleAnimation!, child: AnimatedOpacity( opacity: _opacityIcon, duration: Duration(milliseconds: 200), diff --git a/pubspec.yaml b/pubspec.yaml index 4d8b7b1..a29ec59 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ author: Juan Junior Chauca Flores homepage: https://github.com/TioCoding/flutter_navigation_dot_bar environment: - sdk: ">=2.0.0-dev.68.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: flutter: