context: my app navigation relies on one screen with a scaffold and a BottomNavigationBar containing BottomNavigationBarItems. If you click an item, its index dertermines which widget is picked from a list to serve as body for the scaffold. (Code below)
problem: I'd also like to add a Drawer to the scaffold that can also be used for navigation. I know how to add a drawer, but I don't know how to connect items in there with my navigation.
solution I can see:
I could try writing my own function that determines the index of whatever I click in the drawer and sets my page selection to that index. I don't want to reinvent the wheel though; Is there anything like the combination of "BottomNavigationBar + BottomNavigationBarItems" I could place in the drawer? Am I thinking about this the wrong way?
EDIT: I can also just add a list of items wrapped in individual GestureDetectors and call _selectPage() with a hard coded index ... but that does feel clumsy.
Shortened code of the screen for the tabbed navigation:
class _TabsScreenState extends State<TabsScreen> with WidgetsBindingObserver {
late List<Widget> _pages;
late Timer timer;
int _selectedPageIndex = 0;
#override
void initState() {
_pages = [
HomeScreen(),
FavoritesScreen(),
LookBackScreen(),
InfoScreen(),
];}
void _selectPage(int index) {
setState(() {
_selectedPageIndex = index;
});
}
return Scaffold(
appBar: AppBar(
//
body: _pages[_selectedPageIndex],
//
bottomNavigationBar: BottomNavigationBar(
onTap: _selectPage,
currentIndex: _selectedPageIndex,
type: BottomNavigationBarType.fixed,
items: [
//home
BottomNavigationBarItem(
icon: Icon(Icons.home, color: customColorScheme['Icon 1']),
activeIcon: Icon(Icons.home, color: customColorScheme['Icon 2']),
label: '',
),
//favorite
BottomNavigationBarItem(
icon: Icon(Icons.favorite, color: customColorScheme['Icon 1']),
activeIcon:
Icon(Icons.favorite, color: customColorScheme['Icon 2']),
label: '',
),
//loockback
BottomNavigationBarItem(
icon: Icon(Icons.bar_chart, color: customColorScheme['Icon 1']),
activeIcon:
Icon(Icons.bar_chart, color: customColorScheme['Icon 2']),
label: '',
),
//info & support
BottomNavigationBarItem(
icon: Icon(Icons.info, color: customColorScheme['Icon 1']),
activeIcon: Icon(Icons.info, color: customColorScheme['Icon 2']),
label: '',
),
],
),
);
}
}
Related
List navScreens = [
const HomeScreen(),
const FavoriteScreen(),
const NotificationScreen(),
const MyProfilesScreen(),
];
Scaffold(
body: navScreens.elementAt(selectedIndex),
bottomNavigationBar: BottomNavigationBar(
currentIndex: selectedIndex,
iconSize: 34,
selectedItemColor: ConstColors.green,
unselectedItemColor: ConstColors.black2,
elevation: 10,
onTap: (value) {
setState(() {
selectedIndex = value;
});
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined), label: 'home'),
BottomNavigationBarItem(
icon: Icon(Icons.bookmark_border_outlined), label: 'favorite'),
BottomNavigationBarItem(
icon: Icon(Icons.notifications_none), label: 'notification'),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline), label: 'profile'),
],
),
);
When I switch screens from BottomNavBar (MainScreen) to inside (DetailScreen), then BottomNavBar disappears. If I directly navigate to bottombar screen back from nested screens. It also get disappear. Persistent_bottom_bar is another solution but I want to fix it with built in support. Thanks !
This package suits your need well.
I am creating a bottom navigation bar in flutter. I would like to pick the labels from an array. The following program throws an error "Values in a const list literals must be constants". I understand that the the list of navigation bar items in the scaffold is declared const and we cannot use the non-const string arrays. How to fix this problem?
class _MyHomePageState extends State<MyHomePage> {
int _currentIndex = 0;
// final List _children = [];
Text titleText = new Text('Pensor');
var tabLabels = ['Home', 'Water', 'Insights', 'Cabliration', 'Settings'];
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
title: titleText,
),
// body: _children[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
onTap: onTabTapped,
currentIndex: _currentIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: tabLabels[0], // <-- Here is the error. The tabLabels are not const.
),
BottomNavigationBarItem(
icon: Icon(Icons.water_damage),
label: 'Water',
),
BottomNavigationBarItem(
icon: Icon(Icons.insights),
label: 'Insights',
),
BottomNavigationBarItem(
icon: Icon(Icons.biotech),
label: 'Calibration',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Settings',
),
],
),
);
}
Just remove const
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: tabLabels[0],
),
BottomNavigationBarItem(
icon: Icon(Icons.water_damage),
label: 'Water',
),
BottomNavigationBarItem(
icon: Icon(Icons.insights),
label: 'Insights',
),
BottomNavigationBarItem(
icon: Icon(Icons.biotech),
label: 'Calibration',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Settings',
),
],
I have 4 pages in bottom navigation bar. I am facing a problem related to route that i want to route to a specific page in bottom navigation bar from another page?
e.g I am going to login page and post successful login I want to route user to accountdetails(AccountSetting) but if I am selecting account setting then in that page bottom navigation bar is not showing and if I am routing to bottom nav bar here I am unable to select index of my choice. How can I select index of my choice because I don't want to make new page having bottom nav bar?
class BottomNavBar extends StatefulWidget {
static String routeName = "/bottombar";
#override
_BottomNavBarState createState() => _BottomNavBarState();
}
class _BottomNavBarState extends State<BottomNavBar> {
CartCountController cartCountController = CartCountController();
DoublePressBackBotton doublePressBackBotton = DoublePressBackBotton();
int _selectedIndex = 0;
#override
void initState() {
Future.delayed(Duration(milliseconds: 1000)).then((value) {
cartCountController.cartItemCount();
});
super.initState();
}
#override
void dispose() {
Future.delayed(Duration(milliseconds: 1000)).then((value) {
cartCountController.cartItemCount();
});
super.dispose();
}
List _widgetOptions = [
HomeScreen(),
CategoryList(),
InviteFriend(),
AccountSetting(),
];
void _onItemTapped(
int index,
) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return
// drawer: SideDrawer(),
body: WillPopScope(
child: _widgetOptions.elementAt(_selectedIndex),
onWillPop: () {
return doublePressBackBotton.doubleBack();
},
),
bottomNavigationBar: BottomNavigationBar(
// backgroundColor: Color(0xff202020),
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
backgroundColor: kPrimaryColor,
icon: Icon(
Icons.home_outlined,
color: Colors.white,
),
label: 'Home',
),
BottomNavigationBarItem(
backgroundColor: kPrimaryColor,
icon: Icon(
Icons.category,
color: Colors.white,
),
label: 'Category',
),
BottomNavigationBarItem(
backgroundColor: kPrimaryColor,
icon: ImageIcon(
AssetImage(AppImages.phonecall),
color: Colors.white,
),
label: 'Invite',
),
BottomNavigationBarItem(
backgroundColor: kPrimaryColor,
icon: Icon(
Icons.person_outlined,
color: Colors.white,
),
label: 'Account',
),
],
// fixedColor: Colors.black,
currentIndex: _selectedIndex,
// selectedItemColor: Color(0xffF9C000),
onTap: _onItemTapped,
showUnselectedLabels: true,
selectedItemColor: kPrimaryLightColor,
// unselectedItemColor: Color(0xff737373),
unselectedLabelStyle: GoogleFonts.lato(color: Colors.white),
selectedLabelStyle: GoogleFonts.lato(color: Colors.white),
),
);
// );
}
}
I'm creating this app, and I added a bottom navigation bar, and everything is working just fine, except the background color. I would like the background to change depending which item has been selected. It works just fine when I use type: BottomNavigationBarType.shifting, but not when I change it to type: BottomNavigationBarType.fixed.
The thing is that I don't like the "shifting" behavior, I prefer it "fixed".
I found this example online, but it uses the shifting type:
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
backgroundColor: Colors.teal
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
label: 'Profile',
backgroundColor: Colors.cyan
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Settings',
backgroundColor: Colors.lightBlue,
),
],
type: BottomNavigationBarType.shifting,
currentIndex: _selectedIndex,
selectedItemColor: Colors.white,
unselectedItemColor: Colors.grey,
iconSize: 40,
onTap: _onItemTap,
elevation: 5
)
How could I achieve the same background color changing effect using a bottom navigation bar using type: BottomNavigationBarType.fixed?
Thanks in advance.
Use BackgroundNavigationBar.backgroundColor. Consider this modified example from the docs:
class Option {
final String name;
final IconData icon;
final Color color;
const Option({
required this.name,
required this.icon,
required this.color,
});
}
class HomePageState extends State<HomePage> {
static const List<Option> options = [
Option(name: "Home", icon: Icons.home, color: Colors.red,),
Option(name: "Business", icon: Icons.business, color: Colors.green),
Option(name: "School", icon: Icons.school, color: Colors.purple),
Option(name: "Settings", icon: Icons.settings, color: Colors.pink),
];
int index = 0;
Option get option => options [index];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BottomNavigationBar Sample'),
),
body: Center(
child: Text("Index $index: ${option.name}"),
),
bottomNavigationBar: BottomNavigationBar(
backgroundColor: option.color,
type: BottomNavigationBarType.fixed,
currentIndex: index,
onTap: (value) => setState(() => index = value),
items: [
for (final option in options) BottomNavigationBarItem(
icon: Icon(option.icon),
label: option.name,
),
],
),
);
}
}
I am New to Flutter actually I am not a coder but I am trying to build an app that can do basic things like the sign-in page, sign up, user data showing to the screen, and also I can see each other profile from the app I Stuck in the Bottom Navigation bar here which I never thought that it would be hard to get through.
instead of giving up, I decided to google around and come up with different results (some of them are hard to understand and confusing).
I am trying to build a navigation bar that routs to different pages with minimum memory usage (efficient code)
I am so confused and I don't know now what to do! please help another coder(if someone fixes this I am going to consider myself a coder, don't think too much)
#override
Widget build(BuildContext context) {
PageController _pageController = PageController();
final List<Widget> _tabs = [FeedPage(), ListingPage(), SettingPage()];
int _selectedIndex = 0;
void _onPageChanged(int index) {
setState(() { //Is something wrong with my setState?
_selectedIndex = index;
});
}
void _onItemTapped(int _selectedIndex) {
_pageController.jumpToPage(_selectedIndex);
}
return Scaffold(
body: PageView(
controller: _pageController,
children: _tabs,
onPageChanged: _onPageChanged, //Check it out
physics: NeverScrollableScrollPhysics(),
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex, //I use this
onTap: _onItemTapped,
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
),
title: Text("Home"),
),
BottomNavigationBarItem(
icon: Icon(
Icons.list,
),
title: Text("List"),
),
BottomNavigationBarItem(
icon: Icon(
Icons.person,
),
title: Text("Profile"),
),
],
),
);
}
}
//is this the code bugged? or something wrong in my flutter IED or something I am confused
try this code below, insert this code just before the scaffold perntesis, also dont forget to insert the packacge.
bottomNavigationBar: CurvedNavigationBar(
color: Colors.black26,
backgroundColor: Color(0xFFFFC5C5),
buttonBackgroundColor: Colors.greenAccent,
height: 50.0,
animationCurve: Curves.bounceInOut,
items: <Widget>[
Icon(Icons.translate, size: 20, color: Colors.black),
Icon(Icons.translate, size: 20, color: Colors.black),
Icon(Icons.list, size: 20, color: Colors.black),
Icon(Icons.account_balance, size: 20,
color: Colors.black),
// Icon(Icons.camera, size: 20, color: Colors.black),
],
index: 2,
animationDuration: Duration(milliseconds: 400),
onTap: (index) {
debugPrint("Curent index is $index");
}
)
Okay I see you havent mentioned color in your icons so as page changes let us apply the same logic to avoid confusion.
So let us have a list of colors declared below final list of _tabs
List<Color> selectedColor = [Colors.grey[900],Colors.grey[900],Colors.grey[900]];
Now we have assign these to our icons as
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
color: selectedColor[0], //Add here
),
title: Text("Home"),
),
BottomNavigationBarItem(
icon: Icon(
Icons.list,
color: selectedColor[1], //Add here
),
title: Text("List"),
),
BottomNavigationBarItem(
icon: Icon(
Icons.person,
color: selectedColor[2], //Add here
),
title: Text("Profile"),
),
],
Now due to this mentioned in the list all have a grey colour
void updateColor(int num){
//here I am again declaring it because when I select the other color the list should //always remain same for the effect you want
selectedColor = [Colors.grey[900],Colors.grey[900],Colors.grey[900]];
setState(() {
switch(num){
case 1 : selectedColor[0] = Colors.Red;
break;
case 2 : selectedColor[1] = Colors.Red;
break;
case 3 : selectedColor[2] = Colors.Red;
break;
}
});
}
Now what we will do is call this on your onChanged function or you can also mention it in onTap but I dont understand why you used both at the same time
I will use
void _onItemTapped(int _selectedIndex) {
setState(() { //Is something wrong with my setState?
_selectedIndex = index;
updateColor(_selectedIndex);
});
_pageController.jumpToPage(_selectedIndex);
}
You can simply change the colors in the bottom navigation bar as follows.
Change the main color of
color: Colors.orange,
Change the Background color
backgroundColor: Colors.white,
Change the Icon background-color
buttonBackgroundColor: Colors.orangeAccent,
Change the Icon Size
Icon(Icons.person, size: 30),
The sample code as follows
bottomNavigationBar: CurvedNavigationBar(
color: Colors.orange,
backgroundColor: Colors.white,
buttonBackgroundColor: Colors.orangeAccent,
items: <Widget>[
Icon(Icons.person, size: 30),
Icon(Icons.close, size: 30),
Icon(Icons.settings, size: 30),
],
onTap: (index) {
//Handle button tap
},
),
Hope this will fix your problem.