【问题标题】:Flutter - Pass values between routes using pushReplacementNamedFlutter - 使用 pushReplacementNamed 在路由之间传递值
【发布时间】:2018-10-09 20:27:34
【问题描述】:

我正在尝试使用 Navigator.pushReplacementNamed() 在路由之间传递值,但我没有得到它。

我无法弄清楚数据将退出pushReplacementNamed 并获得routes 密钥的正确语法和逻辑是什么。

你能帮帮我吗?

输入以下代码方便理解:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
      routes: <String, WidgetBuilder> {
        '/form': (BuildContext context) => new FormPage(email: ???, header: {'auth': ???}),
      },
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      floatingActionButton: new FloatingActionButton(
        onPressed: () {
          Navigator.pushReplacementNamed(context, '/form', {email: 'myemail@flutter.com', header: {'auth': '1234'}});
        },
        child: new Icon(Icons.navigate_next),
      ),
    );
  }
}

class FormPage extends StatefulWidget {
  FormPage({Key key, this.email, this.header}) : super(key: key);
  String email;
  Map header;
  @override
  FormPageState createState() => new FormPageState();
}

class FormPageState extends State<FormPage> {
  @override
  Widget build(BuildContext context) {
    return new Container(
      child: new Column(
        children: <Widget>[
          new Text(widget.email),
          new Text(widget.header['auth'])
        ],
      ),
    );
  }
}

修正后:

尝试使用pushReplacementNamed的目的是为了删除路线历史,所以如果用户按下设备的返回按钮回到之前的路线,该路线将不再存在。 Reference

这个实现的原因是在登录页面上使用,如果用户已经通过google sign的身份验证,他会被重定向到传递登录参数的下一页并且无法通过设备的后退按钮返回登录页面.

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
      routes: <String, WidgetBuilder> {
        '/form': (BuildContext context) => new FormPage(), //new
      },
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      floatingActionButton: new FloatingActionButton(
        onPressed: () {
          Navigator.of(context).pushReplacement(                                                         //new
            new MaterialPageRoute(                                                                       //new
              settings: const RouteSettings(name: '/form'),                                              //new
              builder: (context) => new FormPage(email: 'myemail@flutter.com', header: {'auth': '1234'}) //new
            )                                                                                            //new
          );                                                                                             //new
        },
        child: new Icon(Icons.navigate_next),
      ),
    );
  }
}

class FormPage extends StatefulWidget {
  FormPage({Key key, this.email, this.header}) : super(key: key);
  String email;
  Map header;
  @override
  FormPageState createState() => new FormPageState();
}

class FormPageState extends State<FormPage> {
  @override
  Widget build(BuildContext context) {
    return new Container(
      child: new Column(
        children: <Widget>[
          new Text(widget.email),
          new Text(widget.header['auth'])
        ],
      ),
    );
  }
}

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    我认为您可能会错过了解结果的工作原理。结果返回到推送最后一条路由的上一个小部件,并使用await 作为上一次调用push 发回的Future 的结果。你只是想用参数开始一条路线吗?然后你就可以这样做了。

    Navigator.of(context).pushReplacement(
      new MaterialPageRoute(
        settings: const RouteSettings(name: '/form'),
        builder: (context) => new FormPage(
          email: 'myemail@flutter.com',
          header: {'auth': '1234'},
        ),
      ),
    );
    

    【讨论】:

      【解决方案2】:
      1. 您可以使用 Navigator.of(context).pushReplacementNamed('/route', arguments: 'Test String'); 将任何对象作为参数从第一个小部件传递。
      2. 并使用String s = ModalRoute.of(context).settings.arguments; 解析initState() 方法后的参数,如第二个小部件中的didChangeDependencies()build(BuildContext context)

      例如:

      @override
      void didChangeDependencies() {
       RouteSettings settings = ModalRoute.of(context)!.settings;
       if (settings.arguments != null) {
        CustomObject obj = settings.arguments as CustomObject;
       }
       super.didChangeDependencies();
      }
      
      1. 而不是第 2 步。 您还可以通过在 App 小部件中使用 onGenerateRoute: (settings) {} 来使用这些参数初始化小部件类。 例如:

        class App extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
         return MaterialApp(
            /*...*/
             routes: {
               /*Don't add those routes with arguments here..*/
             },
             onGenerateRoute: (settings) {
             if (settings.name == SECOND_SCREEN_ROUTE) {
                 if (settings.arguments != null) {
                   CustomObject obj = settings.arguments as CustomObject;
                   return MaterialPageRoute(
                     builder: (context) {
                       return SecondScreen(obj);
                     },
                   );
                }
               }
               assert(false, 'Need to implement ${settings.name}');
               return null;
              });
          }
        }
        

      【讨论】:

      • 我们如何传递多个参数?我们可以以Map&lt;String, dynamic&gt; 格式传递多个参数吗?请建议。谢谢。
      • 我以Map&lt;String, dynmic&gt; 格式而不是String 传递多个参数,因为我必须传递多个参数。但是出现type 'Null' is not a subtype of type 'Map&lt;String, dynamic&gt;' in type cast 之类的错误。有什么建议吗?
      • @Kamlesh 确保您在 didChangeDependencies() 或 build(BuildContext context) 中解析参数
      • 请更新您的答案并传递 2 个参数,并展示我们如何在 didChangeDependencies() 中获取/使用参数。期待听到你的声音。谢谢。
      • @Kamlesh 用一些例子更新了我的答案。请检查一下。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-30
      • 1970-01-01
      相关资源
      最近更新 更多