I want to create a dynamic BottomNavigationBar so that for each screen I can pass the icons/routes I need on that screen. My bottom.dart file looks like this:
import 'package:flutter/material.dart';
class BottomBar extends StatefulWidget {
final List routesToShow;
BottomBar({Key? key, required this.routesToShow}) : super(key: key);
@override
_BottomBar createState() => _BottomBar();
}
class _BottomBar extends State<BottomBar> {
final Map allBottomMenus = {
'home': {'icon': Icon(Icons.home), 'title': Text('Home'), 'route': '/homepage'},
'profile': {'icon': Icon(Icons.verified_user), 'title': Text('Profile'), 'route': '/profile'},
'info': {'icon': Icon(Icons.info_outline), 'title': Text('Info'), 'route': '/info'},
'previousScreen': {'icon': Icon(Icons.backspace), 'title': Text('Back'), 'route': ''},
};
List<BottomNavigationBarItem> bottomNavigationItems = [];
void _buildBottomNavigation() {
widget.routesToShow.forEach((route) {
if (allBottomMenus.containsKey(route)) {
bottomNavigationItems.add(BottomNavigationBarItem(
icon: allBottomMenus[route]['icon'],
label: allBottomMenus[route]['title'],
));
}
});
}
@override
void initState() {
super.initState();
_buildBottomNavigation();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
items: List.of(bottomNavigationItems),
onTap: (int index) {
print(index);
},
);
}
}
and in the homepage, I call this widget like following:
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final routesToShow = List.filled(3, ['homepage', 'info', 'profile']);
return Scaffold(
body: SafeArea(
child: SingleChildScrollView(
child: Column(
children: [
buildHeader(),
const SizedBox(height: 32.0),
],
),
),
),
bottomNavigationBar: BottomBar(routesToShow: routesToShow),
);
}
}
But I get an error saying:
Failed assertion: line 307 pos 15: 'items.length >= 2': is not true.
Seems like the widget is never executed as there are no items. Any help will be appreciated.
CodePudding user response:
There were two problems with your code, first this line:
final routesToShow = List.filled(3, ['homepage', 'info', 'profile']);
it makes a 2D list, therefore you can not retrieve desired data from it with your forEach
method; so replace it with:
final routesToShow = ['homepage', 'info', 'profile'];
the second problem was your map, BottomNavigationBar
expects to find a String
for label not a Text
widget, so replace it with:
final Map allBottomMenus = {
'home': {'icon': Icon(Icons.home), 'title': 'Home', 'route': '/homepage'},
'profile': {
'icon': Icon(Icons.verified_user),
'title': 'Profile',
'route': '/profile'
},
'info': {
'icon': Icon(Icons.info_outline),
'title': 'Info',
'route': '/info'
},
'previousScreen': {
'icon': Icon(Icons.backspace),
'title': 'Back',
'route': ''
},
};