导航器通过pushNamed传递参数

Syp*_*yph 6 flutter

可能已经有人问过,但我找不到,但是如何将参数传递给命名路由?

这就是我建立路线的方式

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);
      },
    );
Run Code Online (Sandbox Code Playgroud)

这就是你的称呼 Navigator.of(context).pushNamed('home/presentation')

但是,如果我的小部件是new Presentation(arg1, arg2, arg3)怎么办?

bad*_*n77 67

不需要onGenerateRoute。只需使用

var exampleArgument = 'example string';

Navigator.pushNamed(
    context,
    ImagesScreen.routeName,
    arguments: {'exampleArgument': exampleArgument},
);
Run Code Online (Sandbox Code Playgroud)

并提取参数如下:

@override
Widget build(BuildContext context) {
    final arguments = ModalRoute.of(context).settings.arguments as Map;

    if (arguments != null) print(arguments['exampleArgument']);

    return Scaffold(...);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果在 initState() 中我需要传递参数来进行 api 调用怎么办?那里还没有上下文。怎么解决这个问题呢?谢谢 (3认同)
  • 最终参数= ModalRoute.of(context).settings.arguments as Map; 这给出了一个错误,即类型 null 不是类型转换中类型映射的子类型,我不知道为什么。 (3认同)
  • @Adnanhaider 我也有同样的问题。我认为这个答案中的代码假设 settings.arguments 不能为空。就我而言是可以的。所以 `as Map` 试图将 null 转换为 Map,这会导致错误。我首先通过从该行中删除 `as Map` 并添加一个空检查 `final argument = ModalRoute.of(context)!.settings.arguments;` 来解决这个问题。然后 `if (arguments != null) ` 你可以将参数转换为 Map。 (3认同)
  • @cwhisperer您可以尝试使用 WidgetsBinding.instance.addPostFrameCallback((_) {doContextStuff(context); }); 在 initState() 中 (2认同)

Mic*_*son 14

我花了一段时间才注意到这一点,因为我是 Flutter 的新手。但是您使用添加的参数Navigator.pushNamed会直接发送到您推送的小部件而不是用于路由的 MaterialApp。

因此,在小部件中,您可以从中推送一个新屏幕,您将拥有:

Navigator.pushNamed(
   context,
   SomePage.routeName,
   arguments: {
      'v1': 'data1',
      'v2': 'data2',
      'v3': 'data3',
   },
)
Run Code Online (Sandbox Code Playgroud)

您的构造函数中根本不需要这些参数。相反,您可以像其他人所说的那样,在 SomePage 小部件中将它们拉出来;即通过:

final arg = ModalRoute.of(context)!.settings.arguments as Map;
Run Code Online (Sandbox Code Playgroud)

并可以在 SomePage 构建中分配它们,例如:

randomVar1 = arg['v1'];
randomVar2 = arg['v2'];
randomVar3 = arg['v3'];
Run Code Online (Sandbox Code Playgroud)

使用您输入的任何键。

如果您希望 MaterialApp 处理它,那么您可以使用onGenerateRoute方法。我花了很长时间才注意到参数直接进入推送的小部件。对我来说这是违反直觉的。


wir*_*uma 13

pushNamed()现在支持从合并的合并请求开始的参数。如果您迫不及待,请切换至频道masterflutter channel master可能紧随其后flutter upgrade)。

如何发送

    Navigator.pushNamed(ctx, '/foo', arguments: someObject);
Run Code Online (Sandbox Code Playgroud)

如何领取

...
    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,
    );
}
Run Code Online (Sandbox Code Playgroud)

“参数”可以是任何对象,例如地图。

  • @UndercoverCoder `FooRoute` 是第二个/目标屏幕。 (2认同)

Buf*_*low 7

基本上你有两个选择:

  • 使用一些第 3 方包进行路由 - 我认为最好的是Fluro
  • 开发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]);
...
Run Code Online (Sandbox Code Playgroud)


小智 6

参数可以是任何对象,您可以创建一个数组,如您所见:

Navigator.of(context).pushNamed('/upload', arguments: {'_imagePath':_imagePath,
      'num_docfiscal':num_docfiscal,'dta_docfiscal':dta_docfiscal});
Run Code Online (Sandbox Code Playgroud)

并访问路由器类。


Kon*_*zyb 6

使用从 WidgetA 到 WidgetB 的参数进行简单导航

  1. 在 MaterialApp 主小部件中定义路由:
    return MaterialApp(
       routes: {
           '/routeAB': (context) => WidgetB(),
       },
Run Code Online (Sandbox Code Playgroud)
  1. 在 WidgetA 中使用 pushNamed 方法导航到 WidgetB:
  onTap: () { 
     Navigator.pushNamed(context, '/routeAB', 
       arguments: {
          'arg1': val1,
          'arg2': val2,
          ...
Run Code Online (Sandbox Code Playgroud)
  1. 获取 WidgetB 中的参数:
    Map args = ModalRoute.of(context).settings.arguments;
Run Code Online (Sandbox Code Playgroud)

  • 类型 null 不是类型转换中类型映射的子类型,我得到的错误 (2认同)