向命名路由傳遞引數
Navigator 提供了透過通用識別符號在應用的任何部分導航到命名路由的功能。在某些情況下,您可能還需要向命名路由傳遞引數。例如,您可能希望導航到 /user 路由並向該路由傳遞使用者資訊。
您可以使用 Navigator.pushNamed() 方法的 arguments 引數來完成此任務。使用 ModalRoute.of() 方法或在提供給 MaterialApp 或 CupertinoApp 建構函式的 onGenerateRoute() 函式中提取引數。
本示例演示瞭如何使用以下步驟將引數傳遞給命名路由並使用 ModalRoute.of() 和 onGenerateRoute() 讀取引數:
- 定義需要傳遞的引數。
- 建立一個提取引數的小部件。
- 在
routes表中註冊該小部件。 - 導航到該小部件。
1. 定義需要傳遞的引數
#首先,定義需要傳遞給新路由的引數。在此示例中,傳遞兩個資料:螢幕的 title 和一個 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);
}2. 建立一個提取引數的小部件
#接下來,建立一個從小部件 ScreenArguments 中提取並顯示 title 和 message 的小部件。要訪問 ScreenArguments,請使用 ModalRoute.of() 方法。此方法返回帶有引數的當前路由。
// 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)),
);
}
}3. 在 routes 表中註冊小部件
#接下來,向提供給 MaterialApp 小部件的 routes 新增一個條目。routes 定義了應根據路由名稱建立哪個小部件。
MaterialApp(
routes: {
ExtractArgumentsScreen.routeName: (context) =>
const ExtractArgumentsScreen(),
},
)4. 導航到該小部件
#最後,當用戶點選按鈕時,使用 Navigator.pushNamed() 導航到 ExtractArgumentsScreen。透過 arguments 屬性將引數提供給路由。ExtractArgumentsScreen 從這些引數中提取 title 和 message。
// 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'),
),或者,使用 onGenerateRoute 提取引數
#除了直接在小部件內部提取引數外,您還可以在 onGenerateRoute() 函式中提取引數並將它們傳遞給小部件。
onGenerateRoute() 函式根據給定的 RouteSettings 建立正確的路由。
MaterialApp(
// 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;
},
)互動示例
#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);
}