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.
Related
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: '',
),
],
),
);
}
}
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',
),
],
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.
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'm having an app with a bottom navigation bar:
BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Image.asset('assets/icons/inactive/sth.png'),
activeIcon: Image.asset('assets/icons/active/sth.png'),
title: Text('Sth')
),
BottomNavigationBarItem(
icon: Image.asset('assets/icons/inactive/sth.png'),
activeIcon: Image.asset('assets/icons/active/sth.png'),
title: Text('Sth')
),
],
onTap: (int index) {
_currentIndex = index;
},
currentIndex: _currentIndex
)
Now I have some use cases where I want to display the bottomNavigationBar but none of its items should be active.
When setting the currentIndex to a non-existing index, I'm getting an error as expected.
Is there any way to achieve my goal?
Thank you in advance.
You can try something like
bool isInactive;
BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Image.asset('assets/icons/inactive/sth.png'),
activeIcon: isInactive ? Image.asset('assets/icons/active/sth.png') : Image.asset('assets/icons/inactive/sth.png'),
title: Text('Sth')
),
...
// set default unselected
int _selectedIndex = -1;
BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Image.asset('assets/icons/inactive/sth.png'),
activeIcon: Image.asset('assets/icons/active/sth.png'),
title: Text('Sth')
),
BottomNavigationBarItem(
icon: Image.asset('assets/icons/inactive/sth.png'),
activeIcon: Image.asset('assets/icons/active/sth.png'),
title: Text('Sth')
),
],
onTap: (int index) {
setState(() {
_selectedIndex = index;
});
},
// if unselected change select index to 0, else you will get error
currentIndex: (_selectedIndex != -1) ? _selectedIndex : 0,
// add unselected color
unselectedItemColor: Colors.grey,
// if unselected change color to unselectedItemColor
selectedItemColor: (_selectedIndex != -1) ? Colors.blueGrey : Colors.grey,
)