Почему Flutter пытается рендерить '/', а не мой `initialRoute`? - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть приложение Flutter, в котором я пытаюсь глубже погрузиться в маршрутизацию. Когда я использую свойство home в своем виджете MaterialApp, оно кажется совершенно счастливым. Как только я переключаю его на использование 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);
  }
}

Ответы [ 2 ]

1 голос
/ 20 апреля 2020

Благодаря комментарию к моему ответу @pskink, решение довольно очевидно: удаление ведущего / решает проблему.

Этот комментарий в исходном коде показывает, что Navigator разделит строку на / символов и загрузит маршрут для каждого чанка, чтобы сохранить отслеживаемую историю.

0 голосов
/ 20 апреля 2020

Это потому, что он не может найти ни одного маршрута с именем '/ loading', потому что вы создали route карту <String, Function>, тогда как маршруты * WidgetBuilder.

Поэтому попробуйте заменить:

Map<String, Function>

на:

Map<String, WidgetBuilder>
...