├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── lib └── navigation_dot_bar.dart └── pubspec.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://www.dartlang.org/guides/libraries/private-files 2 | 3 | # Files and directories created by pub 4 | .dart_tool/ 5 | .packages 6 | .pub/ 7 | build/ 8 | 9 | # If you're building an application, you may want to check-in your pubspec.lock 10 | pubspec.lock 11 | 12 | # Directory created by dartdoc 13 | # If you don't generate documentation locally you can remove this line. 14 | doc/api/ 15 | 16 | # IntelliJ related 17 | *.iml 18 | *.ipr 19 | *.iws 20 | .idea/ 21 | 22 | \.DS_Store -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: d8cbb80206db06d151206f8b599b7dde5a386a2d 8 | channel: beta 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.1.2] 2 | 3 | * Initial open source release 4 | 5 | ## [0.1.3] 6 | 7 | * Dynamic color 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Vipul Asri 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Navigation Dot Bar 2 | 3 | Una libreria de Flutter, el cual agrega un BottomNavigationBar con un mejor estilo. Inspirada en la aplicacion "Reflectly" 4 | 5 | ![20181111_230822](https://user-images.githubusercontent.com/22163898/48326755-02bf8480-e609-11e8-8825-b81750ea9dfc.gif) 6 | 7 | ## Como usarlo 8 | 9 | Agregue la dependencia a su proyecto, editando el archivo pubspec.yaml. 10 | 11 | ```` 12 | dependencies: 13 | navigation_dot_bar: ^0.1.3 14 | ```` 15 | Importar la libreria a tu proyecto: 16 | ```` 17 | import 'package:navigation_dot_bar/navigation_dot_bar.dart'; 18 | ```` 19 | Usalo de manera sencilla con BottomNavigationDotBar: 20 | ````dart 21 | Scaffold( 22 | appBar: AppBar( title: Text("Demo Bottom Navigation Bar")), 23 | body: Container(), 24 | bottomNavigationBar: BottomNavigationDotBar ( // Usar -> "BottomNavigationDotBar" 25 | items: [ 26 | BottomNavigationDotBarItem(icon: Icons.map, onTap: () { /* Cualquier funcion - [abrir nueva venta] */ }), 27 | BottomNavigationDotBarItem(icon: Icons.alarm_add, onTap: () { /* Cualquier funcion - [abrir nueva venta] */ }), 28 | BottomNavigationDotBarItem(icon: Icons.timer, onTap: () { /* Cualquier funcion - [abrir nueva venta] */ }), 29 | ... 30 | .. 31 | . 32 | ] 33 | ), 34 | ) 35 | ```` 36 | -------------------------------------------------------------------------------- /lib/navigation_dot_bar.dart: -------------------------------------------------------------------------------- 1 | library navigation_dot_bar; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class BottomNavigationDotBar extends StatefulWidget{ 6 | 7 | final List items; 8 | final Color activeColor; 9 | final Color color; 10 | 11 | const BottomNavigationDotBar({@required this.items, this.activeColor, this.color, Key key}): super(key: key); 12 | 13 | @override 14 | State createState() => _BottomNavigationDotBarState(); 15 | 16 | } 17 | 18 | class _BottomNavigationDotBarState extends State{ 19 | 20 | GlobalKey _keyBottomBar = GlobalKey(); 21 | double _numPositionBase, _numDifferenceBase, _positionLeftIndicatorDot; 22 | int _indexPageSelected = 0; 23 | Color _color, _activeColor; 24 | 25 | @override 26 | void initState() { 27 | WidgetsBinding.instance.addPostFrameCallback(_afterLayout); 28 | super.initState(); 29 | } 30 | 31 | _afterLayout(_) { 32 | _color = widget.color ?? Colors.black45; 33 | _activeColor = widget.activeColor ?? Theme.of(context).primaryColor; 34 | final sizeBottomBar = (_keyBottomBar.currentContext.findRenderObject() as RenderBox).size; 35 | _numPositionBase = ((sizeBottomBar.width / widget.items.length)); 36 | _numDifferenceBase = (_numPositionBase - (_numPositionBase / 2) + 2); 37 | setState(() { _positionLeftIndicatorDot = _numPositionBase - _numDifferenceBase; }); 38 | } 39 | 40 | @override 41 | Widget build(BuildContext context) => Container ( 42 | padding: EdgeInsets.fromLTRB(5, 0, 5, 5), 43 | child: Material( 44 | elevation: 5, 45 | borderRadius: BorderRadius.circular(10), 46 | child: Container( 47 | padding: EdgeInsets.symmetric(vertical: 12), 48 | child: Stack( 49 | key: _keyBottomBar, 50 | children: [ 51 | Padding( 52 | padding: EdgeInsets.only(bottom: 12), 53 | child: Row( 54 | mainAxisAlignment: MainAxisAlignment.spaceAround, 55 | children: _createNavigationIconButtonList(widget.items.asMap()) 56 | ), 57 | ), 58 | AnimatedPositioned( 59 | child: CircleAvatar(radius: 2.5, backgroundColor: _activeColor), 60 | duration: Duration(milliseconds: 400), 61 | curve: Curves.fastOutSlowIn, 62 | left: _positionLeftIndicatorDot, 63 | bottom: 0 64 | ), 65 | ], 66 | ), 67 | ) 68 | ), 69 | ); 70 | 71 | List<_NavigationIconButton> _createNavigationIconButtonList(Map mapItem){ 72 | List<_NavigationIconButton> children = List<_NavigationIconButton>(); 73 | mapItem.forEach((index, item) => 74 | children.add(_NavigationIconButton(item.icon, (index == _indexPageSelected) ? _activeColor : _color,item.onTap,() { _changeOptionBottomBar(index); })) 75 | ); 76 | return children; 77 | } 78 | 79 | void _changeOptionBottomBar(int indexPageSelected){ 80 | if(indexPageSelected != _indexPageSelected){ 81 | setState(() { _positionLeftIndicatorDot = (_numPositionBase * (indexPageSelected+1))-_numDifferenceBase; }); 82 | _indexPageSelected = indexPageSelected; 83 | } 84 | } 85 | 86 | } 87 | 88 | class BottomNavigationDotBarItem{ 89 | final IconData icon; 90 | final NavigationIconButtonTapCallback onTap; 91 | const BottomNavigationDotBarItem({@required this.icon, this.onTap}) : assert(icon != null); 92 | } 93 | 94 | typedef NavigationIconButtonTapCallback = void Function(); 95 | 96 | class _NavigationIconButton extends StatefulWidget { 97 | 98 | final IconData _icon; 99 | final Color _colorIcon; 100 | final NavigationIconButtonTapCallback _onTapInternalButton; 101 | final NavigationIconButtonTapCallback _onTapExternalButton; 102 | 103 | const _NavigationIconButton(this._icon, this._colorIcon, this._onTapInternalButton, this._onTapExternalButton, {Key key}): super(key: key); 104 | 105 | @override 106 | _NavigationIconButtonState createState() => _NavigationIconButtonState(); 107 | 108 | } 109 | 110 | class _NavigationIconButtonState extends State<_NavigationIconButton> with SingleTickerProviderStateMixin { 111 | 112 | AnimationController _controller; 113 | Animation _scaleAnimation; 114 | double _opacityIcon = 1; 115 | 116 | @override 117 | void initState() { 118 | super.initState(); 119 | _controller = AnimationController(vsync: this, duration: Duration(milliseconds: 200)); 120 | _scaleAnimation = Tween(begin: 1, end: 0.93).animate(_controller); 121 | } 122 | 123 | @override 124 | Widget build(BuildContext context) => GestureDetector( 125 | onTapDown: (_) { 126 | _controller.forward(); 127 | setState(() { _opacityIcon = 0.7; }); 128 | }, 129 | onTapUp: (_) { 130 | _controller.reverse(); 131 | setState(() { _opacityIcon = 1; }); 132 | }, 133 | onTapCancel: () { 134 | _controller.reverse(); 135 | setState(() { _opacityIcon = 1; }); 136 | }, 137 | onTap: () { 138 | widget._onTapInternalButton(); 139 | widget._onTapExternalButton(); 140 | }, 141 | child: ScaleTransition( 142 | scale: _scaleAnimation, 143 | child: AnimatedOpacity( 144 | opacity: _opacityIcon, 145 | duration: Duration(milliseconds: 200), 146 | child: Icon(widget._icon, color: widget._colorIcon) 147 | ) 148 | ) 149 | ); 150 | } 151 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: navigation_dot_bar 2 | description: A library of Flutter to add a new style in the navigation bar. 3 | version: 0.1.3 4 | author: Juan Junior Chauca Flores 5 | homepage: https://github.com/TioCoding/flutter_navigation_dot_bar 6 | 7 | environment: 8 | sdk: ">=2.0.0-dev.68.0 <3.0.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | dev_dependencies: 15 | flutter_test: 16 | sdk: flutter --------------------------------------------------------------------------------