I've created a BottomNav that has 4 buttons and it navigates fine between them. But i want this BottomNav to be visible in all screens of the app (those screens that are not directly attached to the BottomNav).
How can I approach such a thing?
here's my BottomNav code to be clear:
int _selectedIndex = 0;
//list of widgets that already exist on the bottomNav
static List<Widget> _screens = <Widget>[
PermissionsRequestScreen(),
HomeScreen(title: 'Home'),
NoticesScreen(),
ProfileScreen(),
MoreScreen(),
];
////////////////////////
// bottom nav bar navigator function
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
/////////////////////
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(),
body: Center(
child: _screens.elementAt(_selectedIndex),
),
//bottomNavBar
bottomNavigationBar: createBottomNavBar(),
);
}
///////////////////
// bottom navigation Bar
Widget createBottomNavBar() {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [primaryColor, secondaryColor],
stops: [8, 8],
),
),
child: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: _selectedIndex,
onTap: _onItemTapped,
backgroundColor: Colors.transparent,
iconSize: 22,
selectedItemColor: Colors.white,
unselectedItemColor: Colors.white24,
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.info),
label: 'Notices',
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
),
BottomNavigationBarItem(
icon: Icon(Icons.more_horiz),
label: 'More',
),
],
enableFeedback: true,
),
);
}
I've tried to use pushReplacement when moving from the bottomNav screen to the next one but it doesn't work.
So, i.e.: How to keep the BottomNav visible in the screens that aren't directly attached to the BottomNav??
CodePudding user response:
You can use PageView
to achieve your goal.
Example PageView:
class MainPageView extends StatelessWidget {
MainPageView({Key? key}) : super(key: key);
final pageController = PageController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: SizedBox.expand(
child: PageView(
controller: pageController,
physics: const NeverScrollableScrollPhysics(),
onPageChanged: (_){},
children: const <Widget>[
FirstView(),
SecondView(),
ThirdView(),
FourthView(),
],
),
),
bottomNavigationBar: const NavigationBarView(),
);
}
}
You need to create PageController
to change the page on the screen when an item from BottomNavigation
is selected.
If you have further questions, please don't hesitate to write in the comments.
CodePudding user response:
You can try persistent_bottom_nav_bar package. It is easy to use and also has 20 different style.
If you want to have your own style for the navigation bar, follow these steps
Here is an example of implementation;
class _PersistentNavBarState extends State<PersistentNavBar> {
late PersistentTabController _controller;
@override
void initState() {
_controller = PersistentTabController(initialIndex: 0);
super.initState();
}
List<Widget> _buildScreens() {
return [
HomeScreen(title: 'Home'),
NoticesScreen(),
ProfileScreen(),
MoreScreen(),
];
}
List<PersistentBottomNavBarItem> _navBarsItems() {
return [
PersistentBottomNavBarItem(
icon: Icon(Icons.home),
title: ('Home'),
activeColorPrimary: CupertinoColors.activeBlue,
inactiveColorPrimary: CupertinoColors.systemGrey,
),
PersistentBottomNavBarItem(
icon: Icon(Icons.info),
title: ('Notices'),
activeColorPrimary: CupertinoColors.activeBlue,
inactiveColorPrimary: CupertinoColors.systemGrey,
),
PersistentBottomNavBarItem(
icon: Icon(Icons.person),
title: ('Profile'),
activeColorPrimary: CupertinoColors.activeBlue,
inactiveColorPrimary: CupertinoColors.systemGrey,
),
PersistentBottomNavBarItem(
icon: Icon(Icons.more_horiz),
title: ('More'),
activeColorPrimary: CupertinoColors.activeBlue,
inactiveColorPrimary: CupertinoColors.systemGrey,
),
];
}
@override
Widget build(BuildContext context) {
return PersistentTabView(
context,
controller: _controller,
screens: _buildScreens(),
items: _navBarsItems(),
confineInSafeArea: true,
backgroundColor: Colors.white, // Default is Colors.white.
handleAndroidBackButtonPress: true, // Default is true.
resizeToAvoidBottomInset:
true, // This needs to be true if you want to move up the screen when keyboard appears. Default is true.
stateManagement: true, // Default is true.
hideNavigationBarWhenKeyboardShows:
true, // Recommended to set 'resizeToAvoidBottomInset' as true while using this argument. Default is true.
decoration: NavBarDecoration(
borderRadius: BorderRadius.circular(10.0),
colorBehindNavBar: Colors.white,
),
popAllScreensOnTapOfSelectedTab: true,
popActionScreens: PopActionScreensType.all,
itemAnimationProperties: ItemAnimationProperties(
// Navigation Bar's items animation properties.
duration: Duration(milliseconds: 200),
curve: Curves.ease,
),
screenTransitionAnimation: ScreenTransitionAnimation(
// Screen transition animation on change of selected tab.
animateTabTransition: true,
curve: Curves.ease,
duration: Duration(milliseconds: 200),
),
navBarStyle: NavBarStyle
.neumorphic, // Choose the nav bar style with this property.
);
}
}