rolling_nav_bar 0.0.1

rolling_nav_bar #

A bottom nav bar with layout inspired by this design and with heavily customizable animations, colors, and shapes.

Getting Started #

To get started, place your RollingNavBar in the bottomNavigationCar slot of a Scaffold, wrapped in a widget that provides max height. For example:

Scaffold(
  bottomNavigationBar: Container(
    height: 95,
    child: RollingNavBar(
      // nav items
    ),
  )
);

Alternatively, you can place it directly using a Stack:

Scaffold(
  body: Stack(
    children: <Widget>[
      Positioned(
        bottom: 0,
        height: 95,
        width: MediaQuery.of(context).size.width,
        child: RollingNavBar(
          // nav items
        ),
      )
    ]
  )
);

Customization #

RollingNavBar is heavily customizable and works with 3, 4, or 5 navigation elements. Each element is also fully customizable through the two primary ways to specify child navigation elements.

The first option is to pass a list of IconData objects, along with optional lists of Color objects.

RollingNavBar.iconData(
  iconData: <IconData>[
    Icons.home,
    Icons.people,
    Icons.settings,
  ],
  indicatorColors: <Color>[
    Colors.red,
    Colors.yellow,
    Colors.blue,
  ],
)

The second option is to provide a widget builder, though this comes with some loss of helpful active state management.

RollingNavBar.builder(
  builder: (context, index, info, update) {
    // The `iconData` constructor handles all active state management,
    // but this constructor, as it deals with completed widgets, must
    // assume that you have already made all relevant considerations.
    var textStyle = index == info.nextIndex
      ? TextStyle(color: Colors.white)
      : TextStyle(color: Colors.grey);
    return Text('${index + 1}', style: style);
  },
  indicatorColors: <Color>[
    Colors.red,
    Colors.yellow,
    Colors.blue,
  ],
  numChildren: 3,
)

Animation Types #

RollingNavBar comes with four animation flavors for the active indicator's transition from tab to tab.

The first animation type is the namesake: AnimationType.roll:

RollingNavBar.iconData(
  animationCurve: Curves.easeOut,  // `easeOut` (the default) is recommended here
  animationType: AnimationType.roll,
  baseAnimationSpeed: 200, // milliseconds
  iconData: <IconData>[
    ...
  ],
)
Roll Example

Note: For the roll animation type, your supplied animation speed is a multiplier considered against the distance the indicator must travel. This ensures a constant speed of travel no matter where the user clicks.


The second animation type is a fade-and-reappear effect:

RollingNavBar.iconData(
  animationCurve: Curves.linear, // `linear` is recommended for `shrinkOutIn`
  animationType: AnimationType.shrinkOutIn,
  baseAnimationSpeed: 500, // slower animations look nicer for `shrinkOutIn`
  iconData: <IconData>[
    ...
  ],
)
Shrink-out-in Example

Note: For the shinkOutIn animation type, your supplied animation speed is constant, since the active indicator never travels the intermediate distance.


The third animation type is a spinning version of fade-and-reappear:

RollingNavBar.iconData(
  animationCurve: Curves.linear, // `linear` is recommended for `spinOutIn`
  animationType: AnimationType.spinOutIn,
  baseAnimationSpeed: 500, // slower animations look nicer for `spinOutIn`
  iconData: <IconData>[
    ...
  ],
)
Spin-out-in Example

Note: Like with shinkOutIn, for the spinOutIn animation type, your supplied animation speed is constant, since the active indicator never travels the intermediate distance.


The final animation flavor is a non-animation:

RollingNavBar.iconData(
  // `animationCurve` and `baseAnimationSpeed` are ignored
  animationType: AnimationType.snap,
  iconData: <IconData>[
    ...
  ],
)
Snap Example

Hooking into the animation #

In the demo, the background of the larger hexagon matches the background of the nav bar hexagon. To achieve this and similar effects, two callbacks, onTap and onAnimate, are available. onAnimate can be particularly helpful for syncing visual effects elsewhere in your app with nav bar progress.

Tab Item Text #

If using the iconData constructor, you are also able to pass a list of widgets to render as text below inactive icons.

RollingNavBar.iconData(
  // A list of length one implies the same color for all icons
  iconColors: <Color>[
    Colors.grey[800],
  ],
  iconData: <IconData>[
    Icons.home,
    Icons.friends,
    Icons.settings,
  ],
  iconText: <Widget>[
    Text('Home', style: TextStyle(color: Colors.grey, fontSize: 12)),
    Text('Friends', style: TextStyle(color: Colors.grey, fontSize: 12)),
    Text('Settings', style: TextStyle(color: Colors.grey, fontSize: 12)),
  ]
)
Icon Text Example

Icon badges #

Using the Badges library, RollingNavBar is able to easily expose nav bar badges. The following works with either constructor.

RollingNavBar.iconData(
  badges: <Widget>[
    Text('1', style: TextStyle(Colors.white)),
    Text('1', style: TextStyle(Colors.white)),
    null,
    null,
    Text('1', style: TextStyle(Colors.white)),
  ],
  iconData: <IconData>[
    Icons.home,
    Icons.friends,
    Icons.account,
    Icons.chat,
    Icons.settings,
  ],
Badges Example

Driving Navigation Bar Changes #

You can programmatically change the active navigation bar tab by passing a new activeIndex to the RollingNavBar widget. However, there are two steps to successfully keeping everything in sync.

class _MyAppState extends State<MyApp> {
  int activeIndex;

  /// Handler that responds to navigation events (likely derived
  /// from user clicks) and keeps the parent in sync.
  void _onTap(int index) {
    // Do not call `setState()`!
    activeIndex = index;
  }

  /// Handler for when you want to programmatically change
  /// the active index. Calling `setState()` here causes
  /// Flutter to re-render the tree, which `RollingNavBar`
  /// responds to by running its normal animation.
  void changeActiveIndex(int index) {
    setState((){
      activeIndex = index;
    });
  }

  Widget build(BuildContext context) {
    return RollingNavBar.iconData(
      activeIndex: activeIndex,
      iconData: iconData,
      onTap: _onTap,
    );
  }
}

[0.0.1] - 2019-01-07

  • Removed children constructor in favor of builder pattern

[0.0.1-alpha+8] - 2019-12-28

  • Added customization for badge colors

[0.0.1-alpha+7] - 2019-12-28

  • Added support for icon badges

[0.0.1-alpha+6] - 2019-12-19

  • Fixed typos. Functionally equivalent to 0.0.1-alpha+5

[0.0.1-alpha+5] - 2019-12-19

  • Added ability to programmatically drive new nav bar index

[0.0.1-alpha+4] - 2019-12-17

  • Fixed bug with null error when not passing iconText
  • Added general sanity tests

[0.0.1-alpha-3] - 2019-12-17

  • Added support for icon text

[0.0.1-alpha-2] - 2019-12-17

  • More README clarifications

[0.0.1-alpha-1] - 2019-12-17

  • Variable name clean-up and other documentation enhancements

[0.0.1-alpha] - 2019-12-15

  • Initial release of RollingNavBar with four animation types: roll, snap, fade-out-and-in, and spin-out-and-in

example/README.md

example #

A new Flutter project.

Getting Started #

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  rolling_nav_bar: ^0.0.1

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:rolling_nav_bar/rolling_nav_bar.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
64
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
90
Overall:
Weighted score of the above. [more]
80
Learn more about scoring.

We analyzed this package on Feb 12, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.5
  • Flutter: 1.12.13+hotfix.7

Maintenance suggestions

Package is pre-v0.1 release. (-10 points)

While nothing is inherently wrong with versions of 0.0.*, it might mean that the author is still experimenting with the general direction of the API.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
badges ^1.1.0 1.1.0
flutter 0.0.0
polygon_clipper ^1.0.2 1.0.2
tinycolor ^1.0.2 1.0.2
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.8
pigment 1.0.3
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test