【问题标题】:Why does Flutter try to render '/' rather than my `initialRoute`?为什么 Flutter 尝试渲染 '/' 而不是我的 `initialRoute`?
【发布时间】:2020-04-20 03:39:08
【问题描述】:

我有一个 Flutter 应用程序,我正在尝试更深入地研究路由。当我在MaterialApp 小部件中使用home 属性时,它似乎非常高兴。一旦我将其更改为使用initialRoute,应用程序就会崩溃并显示NoSuchMethodError 和一个错误提示The builder for route '/' returned null - 我的初始路线是'/loading'

错误:

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building Builder(dirty):
Closure call with mismatched arguments: function 'new MyApp.<anonymous closure>'
Receiver: Closure: (BuildContext) => LoadingScreen
Tried calling: new MyApp.<anonymous closure>(Instance of 'StatelessElement', null)
Found: new MyApp.<anonymous closure>(BuildContext) => LoadingScreen

The relevant error-causing widget was: 
  MaterialApp file:///Users/tanner/Documents/Coding/Courses/AppBrewery/Flutter/Clima-Flutter/lib/main.dart:18:12
When the exception was thrown, this was the stack: 
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1      MyApp._buildRoute (package:clima/main.dart:54:30)
#2      MyApp._makeRoute (package:clima/main.dart:43:26)
#3      MyApp._generateRoute.<anonymous closure> (package:clima/main.dart:27:42)
#4      MaterialPageRoute.buildPage (package:flutter/src/material/page.dart:87:27)
...
════════════════════════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The builder for route "/" returned null.
The relevant error-causing widget was: 
  MaterialApp file:///Users/tanner/Documents/Coding/Courses/AppBrewery/Flutter/Clima-Flutter/lib/main.dart:18:12
════════════════════════════════════════════════════════════════════════════════════════════════════

我的路由怪异

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

class MyApp extends StatelessWidget {
  final Map<String, Function> _routes = {
    '/loading': (BuildContext context, LoadingScreenArguments args) =>
        LoadingScreen(args),
    '/location': (BuildContext context, LocationScreenArguments args) =>
        LocationScreen(args),
  };

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
//      home: LoadingScreen(),
      initialRoute: '/loading',
      onGenerateRoute: _generateRoute,
    );
  }

  MaterialPageRoute _generateRoute(RouteSettings settings) {
    return MaterialPageRoute(
      builder: (BuildContext context) => _makeRoute(
        context: context,
        routeName: settings.name,
        arguments: settings.arguments,
      ),
      maintainState: true,
      fullscreenDialog: false,
    );
  }

  Widget _makeRoute({
    @required BuildContext context,
    @required String routeName,
    Object arguments,
  }) {
    final Widget child = _buildRoute(
        context: context, routeName: routeName, arguments: arguments);
    return child;
  }

  Widget _buildRoute({
    @required BuildContext context,
    @required String routeName,
    Object arguments,
  }) {
    print(routeName);
    return _routes[routeName](context, arguments);
  }
}

【问题讨论】:

  • /loading 更改为 loading - 现在它尝试创建两条路由://loading
  • @pskink - 成功了!!为什么它会尝试同时创建//loading? Navigator 是否尝试使用类似于 Web 应用程序的模式匹配进行匹配,因此它会尝试匹配 /** 之前的任何 /
  • 帮助很大!如果您将此作为答案提交,我将接受它作为正确答案!
  • 随意写一个自我回答;-)
  • 顺便说一句,您也可以使用MaterilApp.onGenerateInitialRoutes,但它是一个相当新的功能......

标签: flutter flutter-navigation


【解决方案1】:

感谢@pskink 对我的回答的评论,解决方案非常明显:删除领先的/ 解决了问题。

源代码中的comment 表明Navigator 将在/ 字符上拆分字符串并为每个块加载路由以保留可追溯的历史记录。

【讨论】:

    【解决方案2】:

    这是因为它找不到任何名为“/loading”的路线,因为您已经制作了&lt;String, Function&gt;route 地图,而路线是WidgetBuilder 的。

    所以尝试替换:

    Map<String, Function>
    

    与:

    Map<String, WidgetBuilder>
    

    【讨论】:

    • 这会引发 lint 错误,因为它不希望我将参数对象传递给小部件。有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-18
    • 2014-07-06
    • 2020-10-23
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    相关资源
    最近更新 更多