大家好!我不知道如何正确地重构我的代码。我想通过数组制作一个小部件列表,如何做对?
Hello everyone! I can’t figure out how to properly refactor my code. I want to make a list of widgets through an array, how to do it right?
我的小部件看起来像这样
Widget build(BuildContext context) {
Widget _bottomNavigationMenu() {
return Container(
margin: const EdgeInsets.only(bottom: 30.0),
child: Wrap(
crossAxisAlignment: WrapCrossAlignment.end,
alignment: WrapAlignment.spaceAround,
spacing: 18.0,
runSpacing: 20.0,
children: <Widget>[
BottomMenuBtn(
nameIcon: "assets/icons/gps.png",
onPressed: () {
Navigator.pushNamed(context, '/locationhistory');
},
textBtn: "Location history",
),
BottomMenuBtn(
textBtn: "Email",
nameIcon: "assets/icons/mail.png",
onPressed: () {
Navigator.pushNamed(context, '/email');
},
),
BottomMenuBtn(
textBtn: "Social Media",
nameIcon: "assets/icons/social.png",
onPressed: () {
Navigator.pushNamed(context, '/socialmedia');
},
),
BottomMenuBtn(
textBtn: "Screen Time",
nameIcon: "assets/icons/screen.png",
onPressed: () {
Navigator.pushNamed(context, '/screentime');
},
),
BottomMenuBtn(
textBtn: "Activity report",
nameIcon: "assets/icons/activity.png",
onPressed: () {
Navigator.pushNamed(context, '/activity');
},
),
BottomMenuBtn(
textBtn: "Calls",
nameIcon: "assets/icons/call.png",
onPressed: () {
Navigator.pushNamed(context, '/calls');
},
),
],
),
);
}
我想要这样的东西--->
创建列表?
我尝试通过map方法解析按钮列表,以免观察到如此庞大的代码量。
如何正确映射这个列表?也许我需要别的东西?
.....
children: <Widget> [
bottomMenuLists.map((item) => {
**what write here?**
*BottomMenuBtn(item)* incorrect
})
]
....
感谢大家的回复!
让我们假设您有一个名为 BottomMenuInfo
的 class,如下所示。
class BottomMenuInfo {
String label;
String imagePath;
String route;
BottomMenuInfo({this.label, this.imagePath, this.route});
}
然后您使用上述信息(例如 label
、imagePath
和 route
.
填充问题中提到的列表 bottomMenuLists
最后,您可以遍历此地图并创建 BottomMenuBtn
小部件并将其 return 作为列表,如下所示。
children:
bottomMenuLists.map((BottomMenuInfo item) {
return BottomMenuBtn(
textBtn: item.label,
nameIcon: item.imagePath,
onPressed: () {
Navigator.pushNamed(context, item.route);
},
)
}).toList()
如果你想让你的代码更简洁,你需要抽象通用代码,使其只出现一次,然后以某种方式提供不同的数据。
代码的抽象通常是辅助函数的工作。
一种可能性是:
BottomMenuBtn _makeButton(String text, String iconName, String pushAction) =>
BottomMenuBtn(
textBtn: text,
nameIcon: "assets/icons/$iconName.png",
onPressed: () {
Navigator.pushNamed(context, pushAction);
});
然后您可以使用它来创建按钮,例如:
Widget build(BuildContext context) {
...
children: <Widget>[
_makeButton("Location history", "gps", "/locationhistory"),
_makeButton("Email", "mail", "/email"),
...
_makeButton("Calls", "calls", "/calls"),
],
...
不同于保存这三个数据点的对象列表,然后迭代该列表以创建另一个列表,辅助函数允许您在使用数据的地方(更好的局部性)写入数据,并且语法开销非常小.
唯一我会做其他事情的情况是数据在编译时未知。所以,如果有人递给我一份
class _MenuButtonInfo {
final String text;
final String iconName;
final String pushAction;
_MenuButtonInfo(this.text, this.iconName, this pushAction);
}
然后我会使用像这样的列表文字:
Widget build(BuildContext context) {
...
children: <Widget>[
for (var info in buttonInfos) BottomMenuBtn(
textBtn: info.text,
nameIcon: "assets/icons/${info.iconName}.png",
onPressed: () {
Navigator.pushNamed(context, info.pushAction);
})
],
...
我的小部件看起来像这样
Widget build(BuildContext context) {
Widget _bottomNavigationMenu() {
return Container(
margin: const EdgeInsets.only(bottom: 30.0),
child: Wrap(
crossAxisAlignment: WrapCrossAlignment.end,
alignment: WrapAlignment.spaceAround,
spacing: 18.0,
runSpacing: 20.0,
children: <Widget>[
BottomMenuBtn(
nameIcon: "assets/icons/gps.png",
onPressed: () {
Navigator.pushNamed(context, '/locationhistory');
},
textBtn: "Location history",
),
BottomMenuBtn(
textBtn: "Email",
nameIcon: "assets/icons/mail.png",
onPressed: () {
Navigator.pushNamed(context, '/email');
},
),
BottomMenuBtn(
textBtn: "Social Media",
nameIcon: "assets/icons/social.png",
onPressed: () {
Navigator.pushNamed(context, '/socialmedia');
},
),
BottomMenuBtn(
textBtn: "Screen Time",
nameIcon: "assets/icons/screen.png",
onPressed: () {
Navigator.pushNamed(context, '/screentime');
},
),
BottomMenuBtn(
textBtn: "Activity report",
nameIcon: "assets/icons/activity.png",
onPressed: () {
Navigator.pushNamed(context, '/activity');
},
),
BottomMenuBtn(
textBtn: "Calls",
nameIcon: "assets/icons/call.png",
onPressed: () {
Navigator.pushNamed(context, '/calls');
},
),
],
),
);
}
我想要这样的东西---> 创建列表?
我尝试通过map方法解析按钮列表,以免观察到如此庞大的代码量。
如何正确映射这个列表?也许我需要别的东西?
.....
children: <Widget> [
bottomMenuLists.map((item) => {
**what write here?**
*BottomMenuBtn(item)* incorrect
})
]
....
感谢大家的回复!
让我们假设您有一个名为 BottomMenuInfo
的 class,如下所示。
class BottomMenuInfo {
String label;
String imagePath;
String route;
BottomMenuInfo({this.label, this.imagePath, this.route});
}
然后您使用上述信息(例如 label
、imagePath
和 route
.
bottomMenuLists
最后,您可以遍历此地图并创建 BottomMenuBtn
小部件并将其 return 作为列表,如下所示。
children:
bottomMenuLists.map((BottomMenuInfo item) {
return BottomMenuBtn(
textBtn: item.label,
nameIcon: item.imagePath,
onPressed: () {
Navigator.pushNamed(context, item.route);
},
)
}).toList()
如果你想让你的代码更简洁,你需要抽象通用代码,使其只出现一次,然后以某种方式提供不同的数据。
代码的抽象通常是辅助函数的工作。
一种可能性是:
BottomMenuBtn _makeButton(String text, String iconName, String pushAction) =>
BottomMenuBtn(
textBtn: text,
nameIcon: "assets/icons/$iconName.png",
onPressed: () {
Navigator.pushNamed(context, pushAction);
});
然后您可以使用它来创建按钮,例如:
Widget build(BuildContext context) {
...
children: <Widget>[
_makeButton("Location history", "gps", "/locationhistory"),
_makeButton("Email", "mail", "/email"),
...
_makeButton("Calls", "calls", "/calls"),
],
...
不同于保存这三个数据点的对象列表,然后迭代该列表以创建另一个列表,辅助函数允许您在使用数据的地方(更好的局部性)写入数据,并且语法开销非常小.
唯一我会做其他事情的情况是数据在编译时未知。所以,如果有人递给我一份
class _MenuButtonInfo {
final String text;
final String iconName;
final String pushAction;
_MenuButtonInfo(this.text, this.iconName, this pushAction);
}
然后我会使用像这样的列表文字:
Widget build(BuildContext context) {
...
children: <Widget>[
for (var info in buttonInfos) BottomMenuBtn(
textBtn: info.text,
nameIcon: "assets/icons/${info.iconName}.png",
onPressed: () {
Navigator.pushNamed(context, info.pushAction);
})
],
...