向命名路由传递参数
Navigator
提供了使用通用标识符从应用程序的任何部分导航到命名路由的功能。 在某些情况下,您可能还需要向命名路由传递参数。例如,您可能希望导航到 /user
路由并将用户信息传递到该路由。
您可以使用 Navigator.pushNamed()
方法的 arguments
参数来完成此任务。使用 ModalRoute.of()
方法或在提供给 MaterialApp
或 CupertinoApp
构造函数的 onGenerateRoute()
函数中提取参数。
此示例演示了如何向命名路由传递参数,以及如何使用 ModalRoute.of()
和 onGenerateRoute()
读取参数,步骤如下:
- 定义需要传递的参数。
- 创建一个提取参数的小部件。
- 在
routes
表中注册小部件。 - 导航到该小部件。
1. 定义需要传递的参数
#首先,定义需要传递到新路由的参数。 在此示例中,传递两条数据:屏幕的 title
和 message
。
要传递这两条数据,请创建一个存储此信息的类。
// 你可以将任何对象传递给 arguments 参数。
// 在此示例中,创建一个包含可自定义标题和消息的类。
class ScreenArguments {
final String title;
final String message;
ScreenArguments(this.title, this.message);
}
2. 创建一个提取参数的小部件
#接下来,创建一个提取并显示 title
和 message
来自 ScreenArguments
的小部件。 要访问 ScreenArguments
,请使用 ModalRoute.of()
方法。 此方法返回带有参数的当前路由。
// 一个从 ModalRoute 提取必要参数的小部件。
class ExtractArgumentsScreen extends StatelessWidget {
const ExtractArgumentsScreen({super.key});
static const routeName = '/extractArguments';
@override
Widget build(BuildContext context) {
// 从当前 ModalRoute 设置中提取参数,并将它们强制转换为 ScreenArguments。
final args = ModalRoute.of(context)!.settings.arguments as ScreenArguments;
return Scaffold(
appBar: AppBar(
title: Text(args.title),
),
body: Center(
child: Text(args.message),
),
);
}
}
3. 在 routes
表中注册小部件
#接下来,向提供给 MaterialApp
小部件的 routes
添加一个条目。 routes
定义了根据路由名称应该创建哪个小部件。
MaterialApp(
routes: {
ExtractArgumentsScreen.routeName: (context) =>
const ExtractArgumentsScreen(),
},
)
4. 导航到该小部件
#最后,当用户点击按钮时,使用 Navigator.pushNamed()
导航到 ExtractArgumentsScreen
。 通过 arguments
属性向路由提供参数。ExtractArgumentsScreen
从这些参数中提取 title
和 message
。
// 一个导航到命名路由的按钮。
// 命名路由自己提取参数。
ElevatedButton(
onPressed: () {
// 当用户点击按钮时,
// 导航到命名路由并
// 将参数作为可选
// 参数提供。
Navigator.pushNamed(
context,
ExtractArgumentsScreen.routeName,
arguments: ScreenArguments(
'Extract Arguments Screen',
'This message is extracted in the build method.',
),
);
},
child: const Text('Navigate to screen that extracts arguments'),
),
或者,使用 onGenerateRoute
提取参数
#您可以不必直接在小部件内部提取参数,而是在 onGenerateRoute()
函数内部提取参数并将它们传递给小部件。
onGenerateRoute()
函数根据给定的 RouteSettings
创建正确的路由。
MaterialApp(
// 提供一个函数来处理命名路由。
// 使用此函数来识别正在推送的命名
// 路由,并创建正确的小部件。
onGenerateRoute: (settings) {
// 如果你推送 PassArguments 路由
if (settings.name == PassArgumentsScreen.routeName) {
// 将参数转换为正确的类型:ScreenArguments。
final args = settings.arguments as ScreenArguments;
// 然后,从参数中提取所需数据,并将数据传递给
// 正确的屏幕。
return MaterialPageRoute(
builder: (context) {
return PassArgumentsScreen(
title: args.title,
message: args.message,
);
},
);
}
// 此代码目前仅支持 PassArgumentsScreen.routeName。
// 如果添加其他值,则需要实现它们。此处的断言将帮助我们在调用堆栈中更高的地方提醒我们这一点,因为否则此断言会在框架中的某个地方触发。
assert(false, 'Need to implement ${settings.name}');
return null;
},
)
交互式示例
#import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
ExtractArgumentsScreen.routeName: (context) =>
const ExtractArgumentsScreen(),
},
// Provide a function to handle named routes.
// Use this function to identify the named
// route being pushed, and create the correct
// Screen.
onGenerateRoute: (settings) {
// If you push the PassArguments route
if (settings.name == PassArgumentsScreen.routeName) {
// Cast the arguments to the correct
// type: ScreenArguments.
final args = settings.arguments as ScreenArguments;
// Then, extract the required data from
// the arguments and pass the data to the
// correct screen.
return MaterialPageRoute(
builder: (context) {
return PassArgumentsScreen(
title: args.title,
message: args.message,
);
},
);
}
// The code only supports
// PassArgumentsScreen.routeName right now.
// Other values need to be implemented if we
// add them. The assertion here will help remind
// us of that higher up in the call stack, since
// this assertion would otherwise fire somewhere
// in the framework.
assert(false, 'Need to implement ${settings.name}');
return null;
},
title: 'Navigation with Arguments',
home: const HomeScreen(),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home Screen'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// A button that navigates to a named route.
// The named route extracts the arguments
// by itself.
ElevatedButton(
onPressed: () {
// When the user taps the button,
// navigate to a named route and
// provide the arguments as an optional
// parameter.
Navigator.pushNamed(
context,
ExtractArgumentsScreen.routeName,
arguments: ScreenArguments(
'Extract Arguments Screen',
'This message is extracted in the build method.',
),
);
},
child: const Text('Navigate to screen that extracts arguments'),
),
// A button that navigates to a named route.
// For this route, extract the arguments in
// the onGenerateRoute function and pass them
// to the screen.
ElevatedButton(
onPressed: () {
// When the user taps the button, navigate
// to a named route and provide the arguments
// as an optional parameter.
Navigator.pushNamed(
context,
PassArgumentsScreen.routeName,
arguments: ScreenArguments(
'Accept Arguments Screen',
'This message is extracted in the onGenerateRoute '
'function.',
),
);
},
child: const Text('Navigate to a named that accepts arguments'),
),
],
),
),
);
}
}
// A Widget that extracts the necessary arguments from
// the ModalRoute.
class ExtractArgumentsScreen extends StatelessWidget {
const ExtractArgumentsScreen({super.key});
static const routeName = '/extractArguments';
@override
Widget build(BuildContext context) {
// Extract the arguments from the current ModalRoute
// settings and cast them as ScreenArguments.
final args = ModalRoute.of(context)!.settings.arguments as ScreenArguments;
return Scaffold(
appBar: AppBar(
title: Text(args.title),
),
body: Center(
child: Text(args.message),
),
);
}
}
// A Widget that accepts the necessary arguments via the
// constructor.
class PassArgumentsScreen extends StatelessWidget {
static const routeName = '/passArguments';
final String title;
final String message;
// This Widget accepts the arguments as constructor
// parameters. It does not extract the arguments from
// the ModalRoute.
//
// The arguments are extracted by the onGenerateRoute
// function provided to the MaterialApp widget.
const PassArgumentsScreen({
super.key,
required this.title,
required this.message,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Center(
child: Text(message),
),
);
}
}
// You can pass any object to the arguments parameter.
// In this example, create a class that contains both
// a customizable title and message.
class ScreenArguments {
final String title;
final String message;
ScreenArguments(this.title, this.message);
}
除非另有说明,否则本网站上的文档反映的是 Flutter 的最新稳定版本。页面最后更新于 2025-01-30。 查看源代码 或 报告问题。