单击时重定向到其他页面的按钮的 Flutter 网格
Flutter grid of buttons that redirects to other page when clicked
大家好,我是 Flutter 新手。我有一个可点击按钮的网格。现在它只有两个,但它可以增长到很多。我如何重构它以使其更具动态性并处理许多未来的按钮?就像一个按钮的网格列表,您可以通过单击这些按钮来导航到不同的页面。
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
),
body: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(30.0),
child: GridView.extent(
maxCrossAxisExtent: 150,
crossAxisSpacing: 15.0,
mainAxisSpacing: 15.0,
children: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ProductScreen(),
),
);
},
padding: EdgeInsets.only(top: 33),
child: Column(
children: [
Icon(
Icons.shopping_cart_outlined,
color: Colors.white,
),
Text(
"Products",
style: TextStyle(
color: Colors.white,
),
),
],
),
),
FlatButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => MailScreen(),
),
);
},
padding: EdgeInsets.only(top: 33),
child: Column(
children: [
Icon(
Icons.mail,
color: Colors.white,
),
Text(
"Mail",
style: TextStyle(
color: Colors.white,
),
),
],
),
),
],
),
),
);
}
}
为按钮创建一个单独的小部件,并在参数中传递颜色、图标、文本和路径。
不要在导航器中使用 push
,而是使用 pushNamed
并在此处使用传递的路由名称。
这是一个解决方案:
1。定义 AppAction 模型
class AppAction {
final Color color;
final String label;
final Color labelColor;
final IconData iconData;
final Color iconColor;
final void Function(BuildContext) callback;
AppAction({
this.color = Colors.blueGrey,
this.label,
this.labelColor = Colors.white,
this.iconData,
this.iconColor = Colors.white,
this.callback,
});
}
您也可以使用 route
或其名称来代替回调函数。不过,如果需要,回调将允许您定义其他类型的操作。 (例如:启动外部 URL、触发模态对话框等)
2。定义您的应用程序操作
final List<AppAction> actions = [
AppAction(
label: 'Products',
iconData: Icons.shopping_cart_outlined,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => ProductScreen()));
},
),
AppAction(
label: 'Mails',
iconData: Icons.mail,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => MailScreen()));
},
),
AppAction(
color: Colors.white,
label: 'Urgent',
labelColor: Colors.redAccent,
iconData: Icons.dangerous,
iconColor: Colors.redAccent,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => UrgentScreen()));
},
),
AppAction(
color: Colors.green.shade200,
label: 'News',
labelColor: Colors.black,
iconData: Icons.new_releases,
iconColor: Colors.green,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => NewsScreen()));
},
),
];
3。定义一个通用的 ActionButton
class ActionButton extends StatelessWidget {
final AppAction action;
const ActionButton({
Key key,
this.action,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return OutlinedButton.icon(
onPressed: () => action.callback?.call(context),
style: OutlinedButton.styleFrom(
backgroundColor: action.color,
padding: const EdgeInsets.all(16.0),
),
label: Text(action.label, style: TextStyle(color: action.labelColor)),
icon: Icon(action.iconData, color: action.iconColor),
);
}
}
4。简化您的主页
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppLayout(
pageTitle: 'Home Page',
child: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(30.0),
child: GridView.extent(
maxCrossAxisExtent: 120,
crossAxisSpacing: 15.0,
mainAxisSpacing: 15.0,
children: actions.map((action) => ActionButton(action: action)).toList(),
),
),
);
}
}
瞧!如果需要,这里有一个完整的独立代码示例供您使用:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
title: 'Flutter Demo',
home: HomePage(),
),
);
}
class AppAction {
final Color color;
final String label;
final Color labelColor;
final IconData iconData;
final Color iconColor;
final void Function(BuildContext) callback;
AppAction({
this.color = Colors.blueGrey,
this.label,
this.labelColor = Colors.white,
this.iconData,
this.iconColor = Colors.white,
this.callback,
});
}
final List<AppAction> actions = [
AppAction(
label: 'Products',
iconData: Icons.shopping_cart_outlined,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => ProductScreen()));
},
),
AppAction(
label: 'Mails',
iconData: Icons.mail,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => MailScreen()));
},
),
AppAction(
color: Colors.white,
label: 'Urgent',
labelColor: Colors.redAccent,
iconData: Icons.dangerous,
iconColor: Colors.redAccent,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => UrgentScreen()));
},
),
AppAction(
color: Colors.green.shade200,
label: 'News',
labelColor: Colors.black,
iconData: Icons.new_releases,
iconColor: Colors.green,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => NewsScreen()));
},
),
];
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppLayout(
pageTitle: 'Home Page',
child: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(30.0),
child: GridView.extent(
maxCrossAxisExtent: 120,
crossAxisSpacing: 15.0,
mainAxisSpacing: 15.0,
children:
actions.map((action) => ActionButton(action: action)).toList(),
),
),
);
}
}
class AppLayout extends StatelessWidget {
final String pageTitle;
final Widget child;
const AppLayout({Key key, this.pageTitle, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(pageTitle)),
body: child,
);
}
}
class ActionButton extends StatelessWidget {
final AppAction action;
const ActionButton({
Key key,
this.action,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return OutlinedButton.icon(
onPressed: () => action.callback?.call(context),
style: OutlinedButton.styleFrom(
backgroundColor: action.color,
padding: const EdgeInsets.all(16.0),
),
label: Text(action.label, style: TextStyle(color: action.labelColor)),
icon: Icon(action.iconData, color: action.iconColor),
);
}
}
class ProductScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppLayout(
pageTitle: ('Products Page'),
child: Center(
child: Text('LIST OF PRODUCTS'),
),
);
}
}
class MailScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppLayout(
pageTitle: 'Mail Page',
child: Center(
child: Text('LIST OF MAIL'),
),
);
}
}
class UrgentScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppLayout(
pageTitle: 'Urgent Page',
child: Center(
child: Text('URGENT', style: TextStyle(color: Colors.redAccent)),
),
);
}
}
class NewsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppLayout(
pageTitle: 'News Page',
child: Center(
child: Text('NEWS', style: TextStyle(color: Colors.green)),
),
);
}
}
大家好,我是 Flutter 新手。我有一个可点击按钮的网格。现在它只有两个,但它可以增长到很多。我如何重构它以使其更具动态性并处理许多未来的按钮?就像一个按钮的网格列表,您可以通过单击这些按钮来导航到不同的页面。
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
),
body: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(30.0),
child: GridView.extent(
maxCrossAxisExtent: 150,
crossAxisSpacing: 15.0,
mainAxisSpacing: 15.0,
children: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ProductScreen(),
),
);
},
padding: EdgeInsets.only(top: 33),
child: Column(
children: [
Icon(
Icons.shopping_cart_outlined,
color: Colors.white,
),
Text(
"Products",
style: TextStyle(
color: Colors.white,
),
),
],
),
),
FlatButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => MailScreen(),
),
);
},
padding: EdgeInsets.only(top: 33),
child: Column(
children: [
Icon(
Icons.mail,
color: Colors.white,
),
Text(
"Mail",
style: TextStyle(
color: Colors.white,
),
),
],
),
),
],
),
),
);
}
}
为按钮创建一个单独的小部件,并在参数中传递颜色、图标、文本和路径。
不要在导航器中使用 push
,而是使用 pushNamed
并在此处使用传递的路由名称。
这是一个解决方案:
1。定义 AppAction 模型
class AppAction {
final Color color;
final String label;
final Color labelColor;
final IconData iconData;
final Color iconColor;
final void Function(BuildContext) callback;
AppAction({
this.color = Colors.blueGrey,
this.label,
this.labelColor = Colors.white,
this.iconData,
this.iconColor = Colors.white,
this.callback,
});
}
您也可以使用 route
或其名称来代替回调函数。不过,如果需要,回调将允许您定义其他类型的操作。 (例如:启动外部 URL、触发模态对话框等)
2。定义您的应用程序操作
final List<AppAction> actions = [
AppAction(
label: 'Products',
iconData: Icons.shopping_cart_outlined,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => ProductScreen()));
},
),
AppAction(
label: 'Mails',
iconData: Icons.mail,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => MailScreen()));
},
),
AppAction(
color: Colors.white,
label: 'Urgent',
labelColor: Colors.redAccent,
iconData: Icons.dangerous,
iconColor: Colors.redAccent,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => UrgentScreen()));
},
),
AppAction(
color: Colors.green.shade200,
label: 'News',
labelColor: Colors.black,
iconData: Icons.new_releases,
iconColor: Colors.green,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => NewsScreen()));
},
),
];
3。定义一个通用的 ActionButton
class ActionButton extends StatelessWidget {
final AppAction action;
const ActionButton({
Key key,
this.action,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return OutlinedButton.icon(
onPressed: () => action.callback?.call(context),
style: OutlinedButton.styleFrom(
backgroundColor: action.color,
padding: const EdgeInsets.all(16.0),
),
label: Text(action.label, style: TextStyle(color: action.labelColor)),
icon: Icon(action.iconData, color: action.iconColor),
);
}
}
4。简化您的主页
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppLayout(
pageTitle: 'Home Page',
child: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(30.0),
child: GridView.extent(
maxCrossAxisExtent: 120,
crossAxisSpacing: 15.0,
mainAxisSpacing: 15.0,
children: actions.map((action) => ActionButton(action: action)).toList(),
),
),
);
}
}
瞧!如果需要,这里有一个完整的独立代码示例供您使用:
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
title: 'Flutter Demo',
home: HomePage(),
),
);
}
class AppAction {
final Color color;
final String label;
final Color labelColor;
final IconData iconData;
final Color iconColor;
final void Function(BuildContext) callback;
AppAction({
this.color = Colors.blueGrey,
this.label,
this.labelColor = Colors.white,
this.iconData,
this.iconColor = Colors.white,
this.callback,
});
}
final List<AppAction> actions = [
AppAction(
label: 'Products',
iconData: Icons.shopping_cart_outlined,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => ProductScreen()));
},
),
AppAction(
label: 'Mails',
iconData: Icons.mail,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => MailScreen()));
},
),
AppAction(
color: Colors.white,
label: 'Urgent',
labelColor: Colors.redAccent,
iconData: Icons.dangerous,
iconColor: Colors.redAccent,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => UrgentScreen()));
},
),
AppAction(
color: Colors.green.shade200,
label: 'News',
labelColor: Colors.black,
iconData: Icons.new_releases,
iconColor: Colors.green,
callback: (context) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (_) => NewsScreen()));
},
),
];
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppLayout(
pageTitle: 'Home Page',
child: Container(
margin: EdgeInsets.all(10),
padding: EdgeInsets.all(30.0),
child: GridView.extent(
maxCrossAxisExtent: 120,
crossAxisSpacing: 15.0,
mainAxisSpacing: 15.0,
children:
actions.map((action) => ActionButton(action: action)).toList(),
),
),
);
}
}
class AppLayout extends StatelessWidget {
final String pageTitle;
final Widget child;
const AppLayout({Key key, this.pageTitle, this.child}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(pageTitle)),
body: child,
);
}
}
class ActionButton extends StatelessWidget {
final AppAction action;
const ActionButton({
Key key,
this.action,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return OutlinedButton.icon(
onPressed: () => action.callback?.call(context),
style: OutlinedButton.styleFrom(
backgroundColor: action.color,
padding: const EdgeInsets.all(16.0),
),
label: Text(action.label, style: TextStyle(color: action.labelColor)),
icon: Icon(action.iconData, color: action.iconColor),
);
}
}
class ProductScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppLayout(
pageTitle: ('Products Page'),
child: Center(
child: Text('LIST OF PRODUCTS'),
),
);
}
}
class MailScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppLayout(
pageTitle: 'Mail Page',
child: Center(
child: Text('LIST OF MAIL'),
),
);
}
}
class UrgentScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppLayout(
pageTitle: 'Urgent Page',
child: Center(
child: Text('URGENT', style: TextStyle(color: Colors.redAccent)),
),
);
}
}
class NewsScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AppLayout(
pageTitle: 'News Page',
child: Center(
child: Text('NEWS', style: TextStyle(color: Colors.green)),
),
);
}
}