Skip to content

Instantly share code, notes, and snippets.

@LordOlumide
Last active September 22, 2023 17:24
Show Gist options
  • Select an option

  • Save LordOlumide/3673c001b3720314687797ffc87573ac to your computer and use it in GitHub Desktop.

Select an option

Save LordOlumide/3673c001b3720314687797ffc87573ac to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
class CustomNavigationBar extends StatefulWidget {
final String activeScreen;
CustomNavigationBar({required this.activeScreen});
@override
State<CustomNavigationBar> createState() => _CustomNavigationBarState();
}
class _CustomNavigationBarState extends State<CustomNavigationBar> {
Route _postScreenPageBuilder() {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => PostScreen(),
transitionDuration: const Duration(milliseconds: 200),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
const begin = Offset(0.0, 1.0);
const end = Offset(0.0, 0.0);
final tween = Tween(begin: begin, end: end);
final offsetAnimation = animation.drive(tween);
return SlideTransition(
position: offsetAnimation,
child: child,
);
},
settings: const RouteSettings(name: PostScreen.screen_id),
);
}
Route _noAnimationBuilder({required Widget page, required String pageName}) {
return PageRouteBuilder(
pageBuilder: (context, animation, secondaryAnimation) => page,
transitionDuration: const Duration(milliseconds: 200),
reverseTransitionDuration: const Duration(milliseconds: 200),
transitionsBuilder: (context, animation, secondaryAnimation, child) {
return child;
},
settings: RouteSettings(name: pageName),
);
}
@override
Widget build(BuildContext context) {
// The home screen must be directly underneath every other screen
// For other screens, if we're on home screen, push it.
// Else, pushReplacement it.
return Container(
height: 50,
padding: const EdgeInsets.all(0),
decoration: BoxDecoration(
color: Colors.white,
border: Border(top: BorderSide(width: 0.7, color: Colors.grey[400]!)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
// Home button
Expanded(
child: Column(
children: [
// Top Indicator
widget.activeScreen == HomeScreen.screen_id
? ActiveIndicatorBar()
: SizedBox(height: 2.6),
// Button
NavigationBarItem(
icon: Icons.home,
title: 'Home',
isActive: widget.activeScreen == HomeScreen.screen_id
? true
: false,
onPressed: () {
if (ModalRoute.of(context)!.settings.name !=
HomeScreen.screen_id) {
Navigator.of(context).pop();
}
},
),
],
),
),
// My Network button
Expanded(
child: Column(
children: [
// Top Indicator
widget.activeScreen == MyNetworkScreen.screen_id
? ActiveIndicatorBar()
: SizedBox(height: 2.6),
// Button
NavigationBarItem(
icon: Icons.people,
title: 'My Network',
isActive: widget.activeScreen == MyNetworkScreen.screen_id
? true
: false,
onPressed: () {
if (ModalRoute.of(context)!.settings.name ==
HomeScreen.screen_id) {
Navigator.of(context).push(_noAnimationBuilder(
page: MyNetworkScreen(),
pageName: MyNetworkScreen.screen_id,
));
} else if (ModalRoute.of(context)!.settings.name ==
MyNetworkScreen.screen_id) {
// do nothing
} else {
Navigator.of(context).pushReplacement(_noAnimationBuilder(
page: MyNetworkScreen(),
pageName: MyNetworkScreen.screen_id));
}
},
),
],
),
),
// Post button
Expanded(
child: Column(
children: [
// Top Indicator
widget.activeScreen == PostScreen.screen_id
? ActiveIndicatorBar()
: SizedBox(height: 2.6),
// Button
NavigationBarItem(
icon: Icons.add_box,
title: 'Post',
isActive: widget.activeScreen == PostScreen.screen_id
? true
: false,
onPressed: () {
Navigator.of(context).push(_postScreenPageBuilder());
},
),
],
),
),
// Notifications button
Expanded(
child: Column(
children: [
// Top Indicator
widget.activeScreen == NotificationsScreen.screen_id
? ActiveIndicatorBar()
: SizedBox(height: 2.6),
// Button
NavigationBarItem(
icon: Icons.notifications,
title: 'Notifications',
isActive: widget.activeScreen == NotificationsScreen.screen_id
? true
: false,
onPressed: () {
if (ModalRoute.of(context)!.settings.name ==
HomeScreen.screen_id) {
Navigator.of(context).push(_noAnimationBuilder(
page: NotificationsScreen(),
pageName: NotificationsScreen.screen_id));
} else if (ModalRoute.of(context)!.settings.name ==
NotificationsScreen.screen_id) {
// do nothing
} else {
Navigator.of(context).pushReplacement(_noAnimationBuilder(
page: NotificationsScreen(),
pageName: NotificationsScreen.screen_id));
}
},
),
],
),
),
// Jobs button
Expanded(
child: Column(
children: [
// Top Indicator
widget.activeScreen == JobsScreen.screen_id
? ActiveIndicatorBar()
: SizedBox(height: 2.6),
// Button
NavigationBarItem(
icon: Icons.work,
title: 'Jobs',
isActive: widget.activeScreen == JobsScreen.screen_id
? true
: false,
onPressed: () {
if (ModalRoute.of(context)!.settings.name ==
HomeScreen.screen_id) {
Navigator.of(context).push(_noAnimationBuilder(
page: JobsScreen(), pageName: JobsScreen.screen_id));
} else if (ModalRoute.of(context)!.settings.name ==
JobsScreen.screen_id) {
// do nothing
} else {
Navigator.of(context).pushReplacement(_noAnimationBuilder(
page: JobsScreen(), pageName: JobsScreen.screen_id));
}
},
),
],
),
),
],
),
);
}
}
class NavigationBarItem extends StatelessWidget {
final IconData icon;
final String title;
final bool isActive;
final VoidCallback onPressed;
final Color activeIconColor;
final Color inactiveIconColor;
const NavigationBarItem({
super.key,
required this.icon,
required this.title,
required this.onPressed,
required this.isActive,
this.activeIconColor = Colors.black,
this.inactiveIconColor = Colors.grey,
});
@override
Widget build(BuildContext context) {
return Expanded(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 2),
child: MaterialButton(
onPressed: onPressed,
elevation: 0,
shape: const RoundedRectangleBorder(borderRadius: BorderRadius.zero),
padding: const EdgeInsets.all(0),
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
icon,
color: isActive == true ? activeIconColor : inactiveIconColor,
),
Text(
title,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 10,
color: isActive == true ? activeIconColor : inactiveIconColor,
),
),
],
),
),
),
);
}
}
class ActiveIndicatorBar extends StatelessWidget {
const ActiveIndicatorBar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Hero(
tag: 'bottom_navigation_active_indicator',
child: Container(
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(1),
),
margin: EdgeInsets.only(top: 0.6, right: 3.5, left: 3.5),
constraints: BoxConstraints(
maxHeight: 2,
maxWidth: 90,
),
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment