navigation bar item's label from array - flutter

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',
),
],

Related

how to make BottomNavBar persisent while switching to nested screens in flutter?

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.

bottom navigation bar: Navigate back to nav bar item from any screen in the app / Navigator.pushNamed instead of creating an object instance

I would like to use Navigator.pushNamed(context, '/route-name'); instead of creating an object instance. I'm trying to get back to a single instance of the called screen from multiple screens of the app. Is there any other way to make this possible?
I would like to replace the widget list with navigator routes instances so I can navigate back to my screen from any place in the app. Code below:
class _NavigationWrapperState extends State<NavigationWrapper> {
var bottomWidgetKey = GlobalKey<State<BottomNavigationBar>>();
int _index = 0;
List<Widget> widgets = [
MyIssuesOverview(),
ProjectOverview(),
DashboardWrapper(),
SettingsScreen(),
];
#override
Widget build(BuildContext context) {
return Scaffold(
key: bottomWidgetKey,
body: widgets.elementAt(_index),
bottomNavigationBar: BottomNavigationBar(
selectedItemColor: Colors.blue,
unselectedItemColor: Colors.grey,
onTap: (int idx) => {
setState(() {
_index = idx;
}),
},
currentIndex: _index,
items: [
BottomNavigationBarItem(label: "Home", icon: Icon(Icons.home)),
BottomNavigationBarItem(label: "Projects", icon: Icon(Icons.topic)),
BottomNavigationBarItem(
label: "Dashboard",
icon: Icon(Icons.add_chart),
),
BottomNavigationBarItem(
label: "Timer",
icon: Icon(Icons.lock_clock),
),
BottomNavigationBarItem(
label: "Settings",
icon: Icon(Icons.settings),
)
],
),
);
}
}

Combining bottom navigation bar and a Drawer

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: '',
),
],
),
);
}
}

Flutter bottom navigation bar make item with no route

Is there a way that I can make an item on bottom navigation bar unclickable that doesn't route anywhere?
lets say you want to deactivate deactiveIndex in your navigation bar. use this:
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.business),
label: 'Business',
),
BottomNavigationBarItem(
icon: Icon(Icons.school),
label: 'School',
),
],
currentIndex: _selectedIndex,
selectedItemColor: Colors.amber[800],
onTap:(index){
if(index == deactiveIndex){ return;}
setState((){_selectedIndex=index});
},
),
for more UI representation you can set activeIcon for active indices or change the color and style of reactive index.

Change the background color of the entire bottom navigation bar depending on item selected in Flutter when type is fixed

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,
),
],
),
);
}
}