onGenerateRouteFlutter中和路由的好处或用例是什么。
在我的应用程序的第一页里面,MaterialApp我们可以为我们的应用程序定义路由,我们可以用onGenerateRoute.
两者都用于 NamedRoute。
我有一个疑问,在哪种情况下我需要使用路由以及在哪种情况下我需要使用onGenerateRoute?
Cop*_*oad 38
routes是静态的,不提供诸如将参数传递给小部件、实现不同的功能PageRoute等功能,这就是onGenerateRoute存在的原因。
在给定的代码中,您会发现如何使用onGenerateRoute属性来解析参数并将其发送出去,这对于 simple 来说是不可能的routes。
FooPage被导航一遍routes又BarPage一遍onGenerateRoute。
初始设置在MaterialApp.
void main() {
  runApp(
    MaterialApp(
      routes: {
        '/': (_) => HomePage(), // You can also use MaterialApp's `home` property instead of '/'
        '/foo': (_) => FooPage(), // No way to pass an argument to FooPage.
      },
      onGenerateRoute: (settings) {
        if (settings.name == '/bar') {
          final value = settings.arguments as int; // Retrieve the value.
          return MaterialPageRoute(builder: (_) => BarPage(value)); // Pass it to BarPage.
        }
        return null; // Let `onUnknownRoute` handle this behavior.
      },
    ),
  );
}
Run Code Online (Sandbox Code Playgroud)
home.dart:
class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('HomePage')),
      body: Center(
        child: Column(
          children: [
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, '/foo'),
              child: Text('Go to FooPage'),
            ),
            ElevatedButton(
              onPressed: () => Navigator.pushNamed(context, '/bar', arguments: 42), // Passing argument
              child: Text('Go to BarPage'),
            ),
          ],
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)
foo.dart
class FooPage extends StatelessWidget {
  @override
  Widget build(_) => Scaffold(appBar: AppBar(title: Text('FooPage')));
}
Run Code Online (Sandbox Code Playgroud)
和bar.dart:
class BarPage extends StatelessWidget {
  final int value;
  BarPage(this.value);
  @override
  Widget build(_) => Scaffold(appBar: AppBar(title: Text('BarPage, value = $value')));
}
Run Code Online (Sandbox Code Playgroud)
截图(供参考)
Kir*_*zin 30
没有错误,只是问题报告者使用不当。这是因为他没有将设置对象传递给 onGenerateRoute 方法返回的新 MaterialPageRoute(请参阅问题的最终评论)。[...]
没有深入研究任何细节,这两个属性做同样的事情,但正如@Alireza 指出的那样routes首先被检查。
此外, usingonGenerateRoute为您提供了一个在推送新路由(页面)之前添加自定义业务逻辑的地方。例如,如果要进行一些初始化。
当使用 Navigator.pushNamed 推送命名路线时,会在此地图中查找路线名称。如果该名称存在,则关联的 WidgetBuilder 用于构建 MaterialPageRoute 以执行到新路由的适当转换,包括英雄动画。
当应用导航到命名路由时使用的路由生成器回调。... 如果路由不包含请求的路由,则使用此选项。
重要提示:
你真正想知道的是一个已知的bug的onGenerateRoute财产。
问题是,如果您使用onGenerateRoute创建命名路由,您将无法从页面中的 RouteSettings 对象获取该路由的名称。(虽然附加到设置对象的参数很好)换句话说:
Widget build(BuildContext context) {
    ModalRoute.of(context).settings.name == null;       //bug
    ModalRoute.of(context).settings.arguments != null;  //ok
    ...
Run Code Online (Sandbox Code Playgroud)
如果您想知道当前路线的名称,这可能会影响您。例如,如果你想弹出一些屏幕:
navigator.popUntil(ModalRoute.withName('/login'));
Run Code Online (Sandbox Code Playgroud)
因此,在解决此问题之前,我建议使用该routes:属性。
小智 6
我的解决方案是重新分配MaterialPageRoute的设置,例如:
批量处理:
final routes = {
  '/': (context) => MainPage(),
};
Run Code Online (Sandbox Code Playgroud)
路由设置:
var onGenerateRoute = (RouteSettings settings) {
    final String name = settings.name;
      final Function pageContentBuilder = routes[name];
      if (pageContentBuilder != null) {
        if (settings.arguments != null) {
          final Route route = MaterialPageRoute(
              settings: settings,
              builder: (context) => pageContentBuilder(context, arguments: settings.arguments));
          return route;
        } else {
          final Route route =
              MaterialPageRoute(settings: settings,
                  builder: (context) => pageContentBuilder(context));
          return route;
        }
      }
    };
   
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           16719 次  |  
        
|   最近记录:  |