This plugin is also available as a template in ApparenceKit.
🚀 Overview
Bart is very simple solution to implement tabulation system layout with Navigator into your application.
- 📱 Material & Cupertino themes available.
- 🤝 Automatic theme switching between material & cupertino.
- 🛣 Inner routing inside tab.
- 🥷 Parent routing (over tabbar content).
- 😌 Very easy to implement.
- 🪄 Show AppBar on demand (automatically animated).
- 🚀 Create your own bottom bar design if you need it.
- 👻 Hide/Show bottom bar when you need
- 🗃 Cache route page if you need to restore state.
🧐 Live example
📖 Installation
Install the package
flutter pub add bart
Import the package
import 'package:bart/bart.dart';
🚀 Get started
- Define in your page the routing tab
List<BartMenuRoute> subRoutes() {
return [
BartMenuRoute.bottomBar(
label: "Home",
icon: Icons.home,
path: '/home',
pageBuilder: (context) => PageFake(
key: PageStorageKey<String>("home"), // this is required to enable state caching
Colors.red,
),
),
BartMenuRoute.bottomBar(
label: "Library",
icon: Icons.video_library_rounded,
path: '/library',
pageBuilder: (context) => PageFake(Colors.blueGrey),
),
BartMenuRoute.bottomBar(
label: "Profile",
icon: Icons.person,
path: '/profile',
pageBuilder: (context) => PageFake(Colors.yellow),
),
BartMenuRoute.innerRoute( // add an inner route, no item will be added in bottom bar
path: '/subpage',
pageBuilder: (context) =>
PageFake(Colors.greenAccent, child: Text("Sub Route page")),
),
];
}
What are the differences between innerRoute & bottomBar ?
This creates a route with a bottom menu item:
BartMenuRoute.bottomBar(...)
This creates a route that you can push within your scaffold body (no extra item will be added in bottom bar)
BartMenuRoute.innerRoute(...)
- Create your main page which include the Bart tabbar Scaffold
class MainPageMenu extends StatelessWidget {
const MainPageMenu({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BartScaffold(
routesBuilder: subRoutes, // add a reference to the subRoutes list you created before
bottomBar: BartBottomBar.adaptive(), // add the bottom bar (see below for other options)
);
}
}
🏞 Bottom bar themes
Bart include 4 ways to display a bottom bar:
BartBottomBar.cupertino() // iOS look.
BartBottomBar.material3() // Android look.
BartBottomBar.adaptive() // automatically select between cupertino & material depending on the device.
BartBottomBar.custom() // your own design
To custom the bottom bar, simply extends BartBottomBarCustom
and create your own bottom bar like SimpleBottomBar
(in example project).
🤖 Material 3 bottom bar
If you want to custom your material 3 bottom bar, you can use the BottomNavigationBarThemeData
class in your theme.
ThemeData(
navigationBarTheme: NavigationBarThemeData(
backgroundColor: Colors.orange.shade100,
indicatorColor: Colors.orange.shade700,
),
)
🗃 Bottom icon notfication badge
You can add a notification badge on your bottom bar icon.
To do that, you need to use the BartMenuRoute.bottomBarBuilder
method instead of BartMenuRoute.bottomBar
in your route definitions:
BartMenuRoute.bottomBarBuilder(
label: "Library",
builder: (context) => BottomBarIcon.builder(
icon: const Icon(Icons.video_library_outlined),
notificationBuilder: (context) => Container(
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
padding: const EdgeInsets.all(4),
child: const Text(
"1",
style: TextStyle(color: Colors.white, fontSize: 10),
),
),
),
path: '/library',
pageBuilder: (parentContext, tabContext, settings) => const FakeListPage(
key: PageStorageKey<String>("library"),
),
transitionDuration: bottomBarTransitionDuration,
transitionsBuilder: bottomBarTransition,
),
🌏 Web sidebar menu
You can choose to use the material sidebar NavigationRail
Like this
return BartScaffold(
routesBuilder: subRoutes,
showBottomBarOnStart: true,
bottomBar: BartBottomBar.material3(),
sideBarOptions: RailSideBarOptions(
extended: true,
gravity: Gravity.left,
),
)
(To change the theme you can do it like all regular material theme in the ThemeData).
Or you can make your own
return BartScaffold(
routesBuilder: subRoutes,
showBottomBarOnStart: true,
bottomBar: BartBottomBar.material3(),
sideBarOptions: CustomSideBarOptions(
gravity: Gravity.left,
sideBarBuilder: ((onTapItem, currentItem) => ...)
),
)
🗃 State caching
How it works 🤔 ?
Imagine you got a page with a counter. You increment this counter and change tab. You want this tab to come back with the incremented counter?.
Bart include a caching system to implement this feature.
By default state caching is enabled. But you can override it:
BartMenuRoute.bottomBar(cache: false)
How to use it 🤓 ?
Your tab pages you want to be cached must use a PageStorageKey
property:
BartMenuRoute.bottomBar(
label: "Library",
icon: Icons.video_library_rounded,
path: '/library',
pageBuilder: (context, settings) => PageFake(
key: PageStorageKey<String>("library"), // add this property
child: Text('Cached page !'),
),
🗃 Show/Hide animated AppBar
You can show an animated AppBar or hide it whenever you want inside all your Bart sub pages.
AppBar will automatically shows or hide with a smooth animation
Simply add the AppBarNotifier mixin like this:
class MyPage extends StatelessWidget with AppBarNotifier {
const MyPage({ Key? key }) : super(key: key);
@override
Widget build(BuildContext context) {
// use the update app bar method to dynamically change app bar
updateAppBar(context, AppBar(title: Text("test")));
// now call you can call show method that will start animation
showAppBar(context);
return Container();
}
}
To hide app bar, just execute this code inside your widget with AppBarNotifier
hideAppBar(context);
You can also use Actions to performs AppBar related actions
Actions.invoke(context, AppBarBuildIntent(AppBar(title: Text("title text"))));
Actions.invoke(context,AppBarAnimationIntent.show());
Actions.invoke(context,AppBarAnimationIntent.hide());
🫥 Show/hide bottom bar
Sometimes you wants to hide the bottom menu bar. As this is possible for the appbar you can use a mixin for that. It just require to be called from a sub context of the BartScaffold.
Actions.invoke(context, BottomBarIntent.show());
Actions.invoke(context, BottomBarIntent.hide());
Or use the mixin
class MyPage extends StatelessWidget with BartNotifier {
const MyPage({ Key? key }) : super(key: key);
@override
Widget build(BuildContext context) {
// directly show the bottom bar
showBottomBar(context);
// directly hide the bottom bar
hideBottomBar(context);
return Container();
}
}
💫 Transitions between items
You can use the official animation plugin to create better transition or create your owns.
Example:
BartMenuRoute.bottomBar(
label: "Library",
icon: Icons.video_library_rounded,
path: '/library',
pageBuilder: (context, settings) => PageFake(Colors.blueGrey),
transitionDuration: Duration(milliseconds: 500),
transitionsBuilder: (context, anim1, anim2, widget) => FadeThroughTransition(
animation: anim1,
secondaryAnimation: anim2,
child: widget,
),
),
📣 Sponsor
Initiated and sponsored by Apparence.io.
👥 Contribution
Contributions are welcome. Contribute by creating a PR or create an issue 🎉.
Libraries
- bart
- bart/bart_appbar
- bart/bart_bottombar_actions
- bart/bart_model
- bart/bart_scaffold
- bart/router_delegate
- bart/widgets/animated_appbar
- bart/widgets/bottom_bar/bottom_bar
- bart/widgets/bottom_bar/bottombar_icon
- bart/widgets/bottom_bar/styles/bottom_bar_cupertino
- bart/widgets/bottom_bar/styles/bottom_bar_custom
- bart/widgets/bottom_bar/styles/bottom_bar_material