动态 BottomNavigationBarItems 抛出错误 'items.length >= 2':不正确
Dynamic BottomNavigationBarItems throwing error 'items.length >= 2': is not true
我想创建一个动态的 BottomNavigationBar,这样我就可以在每个屏幕上传递我需要的 icons/routes。我的 bottom.dart 文件如下所示:
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);
},
);
}
}
在主页中,我这样称呼这个小部件:
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),
);
}
}
但我收到一条错误消息:
Failed assertion: line 307 pos 15: 'items.length >= 2': is not true.
由于没有项目,该小部件似乎从未执行过。任何帮助将不胜感激。
您的代码有两个问题,首先是这一行:
final routesToShow = List.filled(3, ['homepage', 'info', 'profile']);
它制作了一个二维列表,因此您无法使用 forEach
方法从中检索所需的数据;所以将其替换为:
final routesToShow = ['homepage', 'info', 'profile'];
第二个问题是您的地图,BottomNavigationBar
期望为标签找到 String
而不是 Text
小部件,因此将其替换为:
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': ''
},
};
我想创建一个动态的 BottomNavigationBar,这样我就可以在每个屏幕上传递我需要的 icons/routes。我的 bottom.dart 文件如下所示:
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);
},
);
}
}
在主页中,我这样称呼这个小部件:
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),
);
}
}
但我收到一条错误消息:
Failed assertion: line 307 pos 15: 'items.length >= 2': is not true.
由于没有项目,该小部件似乎从未执行过。任何帮助将不胜感激。
您的代码有两个问题,首先是这一行:
final routesToShow = List.filled(3, ['homepage', 'info', 'profile']);
它制作了一个二维列表,因此您无法使用 forEach
方法从中检索所需的数据;所以将其替换为:
final routesToShow = ['homepage', 'info', 'profile'];
第二个问题是您的地图,BottomNavigationBar
期望为标签找到 String
而不是 Text
小部件,因此将其替换为:
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': ''
},
};