以前可能会被问到,但我找不到它,但是如何将参数传递给命名路由?
这就是我建立路线的方式
Widget build(BuildContext context) {
return new Navigator(
initialRoute: 'home/chooseroom',
onGenerateRoute: (RouteSettings settings) {
WidgetBuilder builder;
switch (settings.name) {
case 'home/chooseroom':
// navigates to 'signup/choose_credentials'.
builder = (BuildContext _) => new ChoosePage();
break;
case 'home/createpage':
builder = (BuildContext _) => new CreateRoomPage();
break;
case 'home/presentation':
builder = (BuildContext _) => new Presentation();
break;
default:
throw new Exception('Invalid route: ${settings.name}');
}
return new MaterialPageRoute(builder: builder, settings: settings);
},
);
这就是你的称呼
Navigator.of(context).pushNamed('home/presentation')
但是如果我的小部件是new Presentation(arg1, arg2, arg3)
怎么办?
答案 0 :(得分:7)
pushNamed()
现在支持自merged pull request开始的参数。如果您迫不及待,请切换到频道master
(flutter channel master
,然后再跟flutter upgrade
)。
如何发送:
Navigator.pushNamed(ctx, '/foo', arguments: someObject);
如何接收:
...
return MaterialApp(
...
onGenerateRoute: _getRoute,
...
);
...
Route<dynamic> _getRoute(RouteSettings settings) {
if (settings.name == '/foo') {
// FooRoute constructor expects SomeObject
return _buildRoute(settings, new FooRoute(settings.arguments));
}
return null;
}
MaterialPageRoute _buildRoute(RouteSettings settings, Widget builder) {
return new MaterialPageRoute(
settings: settings,
builder: (ctx) => builder,
);
}
“参数”可以是任何对象,例如地图。
答案 1 :(得分:3)
基本上,您有2个选择:
onGenerateRoute
。此选项仅限您可以传递的参数(字符串/数字)要使用第二个选项,假设您要传递三个参数:Navigator.of(context).pushNamed('home/presentation:arg1:1337:hello')
MaterialApp (
... ,
onGenerateRoute: handleRoute,
routes:... , )
Route<dynamic> handleRoute(RouteSettings settings) {
WidgetBuilder builder;
final List<String> uri = settings.name.split('/');
if (uri[0].startsWith('home')) {
// handle all home routes:
if(uri[1].startsWith('presentation:'){
// cut slice by slice
final String allArgs =
uri[1].substring('presentation:'.length);
final List<String> args = allArgs.split(':');
// use your string args
print(args[0]); // prints "arg1"
int x = int.parse(args[1]); // becomes 1337
print(args[2]); // prints "hello"
builder = (ctx)=> Presentation(args[0],args[1],args[2]);
...
答案 2 :(得分:3)
不需要onGenerateRoute
。只需使用
Navigator.pushNamed(
context,
ImagesScreen.routeName,
arguments: {'path': path}
);
并按如下所示提取参数:
@override
Widget build(BuildContext context) {
final Map arguments = ModalRoute.of(context).settings.arguments as Map;
if (arguments != null) print(arguments['path']);
return Scaffold(...);
}
答案 3 :(得分:2)
使用从WidgetA到WidgetB的参数进行简单导航
return MaterialApp(
routes: {
'/routeAB': (context) => WidgetB(),
},
onTap: () {
Navigator.pushNamed(context, '/routeAB',
arguments: {
'arg1': val1,
'arg2': val2,
...
Map args = ModalRoute.of(context).settings.arguments;
答案 4 :(得分:1)
参数可以是任何对象,可以创建一个数组,如下所示:
Navigator.of(context).pushNamed('/upload', arguments: {'_imagePath':_imagePath,
'num_docfiscal':num_docfiscal,'dta_docfiscal':dta_docfiscal});
并访问路由器类。
答案 5 :(得分:1)
对于具有多个参数或动态对象的named Routes
,您需要执行以下操作(这是MVVM模式示例):
导航器:
void navigateEditParty(int index) {
_navigationService.navigateTo(PartyEditRoute,
arguments: {"hunter": hunter, "index": index});
}
路由器:
case PartyEditRoute:
Map args = settings.arguments;
return _getPageRoute(
routeName: settings.name,
viewToShow: PartyEditView(
hunter: args["hunter"],
index: args["index"],
),
);
班级:
PartyEditView({Key key, this.hunter, this.index}) : super(key: key);
答案 6 :(得分:1)
传递参数:
Navigator.pushNamed(YourScreen.routeName, arguments: {"title":myTitle, "user_name":userName});
提取参数:
Map<String, dynamic> arguments = new Map<String, dynamic>.from(settings.arguments);
page = MyRecordingScreen(title: arguments["title"], tags: arguments["user_name"], );
答案 7 :(得分:0)
始终最好将参数包装在一个对象中,以避免容易出错的代码。
下面是如何用飞镖实现它的工作示例。
发送
Navigator.of(context).pushNamed(Routes.submitSuccess, arguments: successModel);
接收
case Routes.submitSuccess:
if (settings.arguments is SubmitSuccessModel) {//Check for instance here
return CupertinoPageRoute(
builder: (_) =>
SubmitSuccessPage(successModel: settings.arguments));
}
模型对象
class SubmitSuccessModel {
SubmitSuccessModel(
{this.title, this.desc, this.actionButtonName, this.widget});
String title;
String desc;
String actionButtonName;
Widget widget;
}
final SubmitSuccessModel successModel = SubmitSuccessModel(
title: 'Title',
desc: 'Desc',
actionButtonName: 'Done',
);
答案 8 :(得分:0)
注意:new routing options may be available soon。
这可能吗?
将
push
与RouteSettings
参数一起使用,以指定命名的路由。
这样,您可以以类型安全的方式将任何类型的参数(包括对象)直接传递到目标Widget,并使用arguments
跳过。您不需要create a single-use throwaway arguments class或地图。
RouteSettings
中的 push
可以为导航堆栈提供一个命名的Route
,您可以在以后的路由决策中搜索/使用它,就像使用{{1 }}。
要对命名路由使用pushNamed
,请在路由名称中使用push
参数。
示例:用户登录RouteSettings
,现在您希望Page1
从push
到Page1
在Page2
调用中,将Page1
对象(User
)直接传递到loggedInUser
中,并在您的Page2
参数中使用Navigator.push
参数路由名称(RouteSettings
)。
/page2
在Page2小部件中,您可以期望并直接使用Navigator.push(context, MaterialPageRoute(
builder: (context) => Page2(user: loggedInUser),
settings: RouteSettings(name: '/page2')
));
对象。
User
以后您可以使用class Page2 extends StatefulWidget {
final User loggedInUser;
Page2(this.loggedInUser);
@override
_Page2State createState() => _Page2State();
}
class _Page2State extends State<Page2> {
User loggedInUser;
@override
void initState() {
super.initState();
loggedInUser = widget.loggedInUser;
print(loggedInUser.name);
}
@override
Widget build(BuildContext context) {
}
}
路由名称。例如,如果您在/page2
,并且想/page3
,那么就可以。
Flutter的popUntil(context, ModalRoute.withName('/page2'))
类显示Navigator
使用pushNamed
+ routeNamed
,而push
使用routeNamed
。
RouteSettings
Future<T> pushNamed<T extends Object>(
String routeName, {
Object arguments,
}) {
return push<T>(_routeNamed<T>(routeName, arguments: arguments));
}
答案 9 :(得分:0)
我花了一段时间才注意到这一点,因为我是 Flutter 的新手。但是您使用 Navigator.pushNamed
添加的参数会直接发送到您推送的小部件,而不是用于路由的 MaterialApp。
您的构造函数中根本不需要这些参数。相反,您可以像其他人所说的那样在小部件中将它们拉出;即通过:
final arg = ModalRoute.of(context)!.settings.arguments as Map;
并且可以像这样分配它们:
randomVar1 = arg['v1'];
randomVar2 = arg['v2'];
randomVar3 = arg['v3'];
使用您输入的任何键。
如果您希望 MaterialApp 处理它,那么您可以使用 onGenerateRoute 方法。这让我永远注意到参数直接进入推送的小部件。对我来说,这是违反直觉的。
答案 10 :(得分:0)
我花了一段时间才注意到这一点,因为我是 Flutter 的新手。但是您使用 Navigator.pushNamed
添加的参数会直接发送到您推送的小部件,而不是用于路由的 MaterialApp。
因此,在小部件中,您将获得一个新屏幕:
Navigator.pushNamed(
context,
SomePage.routeName,
arguments: {
'v1': 'data1',
'v2': 'data2',
'v3': 'data3',
},
)
您的构造函数中根本不需要这些参数。相反,您可以像其他人所说的那样在 SomePage 小部件中将它们拉出;即通过:
final arg = ModalRoute.of(context)!.settings.arguments as Map;
并且可以在 SomePage 构建中分配它们,例如:
randomVar1 = arg['v1'];
randomVar2 = arg['v2'];
randomVar3 = arg['v3'];
使用您输入的任何键。
如果您希望 MaterialApp 处理它,那么您可以使用 onGenerateRoute 方法。这让我永远注意到参数直接进入推送的小部件。对我来说,这是违反直觉的。
答案 11 :(得分:0)
screen_1.dart
Navigator.of(context).pushNamed('/screen2',arguments: {'var1': val1 ,'var2': val2, "var3": val3 ,"var4" : val4}); //sending of the values to route_generator.dart
route_generator.dart
class RouteGenerator {
static Route<dynamic> generateRoute(RouteSettings settings) //from screeen_1.dart
{
// Getting arguments passed in while calling Navigator.pushNamed
Map args = settings.arguments;
switch (settings.name) {
case '/screen2':
if (args is Map) {
return MaterialPageRoute(
builder: (_) => screen_2(args),
);
}
return _errorRoute(); //optional written in a scaffold when any error arrises
default:
return _errorRoute(); //optional written in a scaffold when any error arrises
}
screen_2.dart
screen_2(Map args) //follow the params from the route_generator.dart
{
return Scaffold(
body: FutureBuilder(
future: _screen_2EndpointProvider.fetchScreen_2(args['var1'], args["var2"], args['var3'], args['var4']), //API call inside which it called the args
builder: (context, snapshot) {
return snapshot.hasData
? screen_2(param: snapshot.data)
: Center(child: CircularProgressIndicator());
}),
);
}
我试图提供一个简单的例子,如果它对任何人都有帮助,因为经过大量试验后我遇到了同样的错误。
答案 12 :(得分:-1)
// 我们要导航的主屏幕
Navigator.pushNamed(
context,
"/ScreenName",
arguments: {
'id': "20"
});
我在使用 NavigationRoutes 时也遇到了同样的问题
class NavigationRoutes {
static Route<dynamic> generateScreenRoute(RouteSettings settings) {
// TODO below we are able to get Arguments list
Map args = settings.arguments;
switch (settings.name) {
case "Screen Name":
return MaterialPageRoute(builder: (context) => ScreenName(args));
// TODO pass above argument here and get in the form of Constructor in Screen
// Name Class
}
}