router onRouteGenerated: только в дочернем виджете вместо установки в виджете приложения материала - PullRequest
1 голос
/ 24 апреля 2020

Я хочу иметь нижнюю панель навигации и использовать именованные маршруты (в основном, для веб-флаттера).

Поэтому мне всегда нужно скаффолд с панелью вкладок в качестве основы и использование виджета навигатора в качестве его тела для содержание. Это работает нормально. Проблема в том, что если я перехожу на вторую вкладку и перезагружаю приложение в веб-приложении, я получаю следующее сообщение об ошибке:

══╡ EXCEPTION CAUGHT BY FLUTTER FRAMEWORK ╞═════════════════════════════════════════════════════════
The following message was thrown:
Could not navigate to initial route.
The requested route name was: "/2"
There was no corresponding route in the app, and therefore the initial route specified will be
ignored and "/" will be used instead.

Я знаю, что получаю это сообщение об ошибке, так как не указаны маршруты / onRouteGenerated на уровне приложения материала. Но я скорее не хочу указывать его там, потому что мне всегда нужен TabBarWidget и я не хочу заменять его другим виджетом, вместо этого я хочу показать содержимое внутри него.

Поэтому возникает вопрос: можно ли делегировать onRouteGenerated «вызов» дочернему навигатору, который находится в теле tabBarWidget? Или есть лучшее решение?

Пример кода:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';


void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  // This widget is the root of your application.
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [
        DefaultMaterialLocalizations.delegate,
        DefaultCupertinoLocalizations.delegate
      ],
      home: TabBarWidget(),
    );
  }
}

class TabBarWidget extends StatefulWidget {
  @override
  TabBarWidgetState createState() => TabBarWidgetState();
}

class TabBarWidgetState extends State<TabBarWidget> {

  int currentIndex = 0;
  final _navigatorKey = GlobalKey<NavigatorState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      bottomNavigationBar: CupertinoTabBar(
        currentIndex: currentIndex,
        onTap: (number) => _itemChanged(number),
        items: [
          BottomNavigationBarItem(
              icon: Icon(CupertinoIcons.mail), title: Text("1")),
          BottomNavigationBarItem(
              icon: Icon(CupertinoIcons.mail), title: Text("2")),
        ],
      ),
      body: Navigator(
        key: _navigatorKey,
        initialRoute: "/1",
        onGenerateRoute: RouteGenerator.generateRoute,
      ),
    );
  }


  _itemChanged(int number) {
    currentIndex = number;
    setState(() {});

    String path;

    switch (number) {
      case 0:
        path = "/1";
        break;
      case 1:
        path = "/2";
        break;
      default:
        path  = "/1";
        break;
    }
    _navigatorKey.currentState.pushReplacementNamed(path);
  }
}

class RouteGenerator {
  static Route<dynamic> generateRoute(RouteSettings settings) {
    switch (settings.name) {
      case '/1':
        return MaterialPageRoute(builder: (_) => ScreenOne(), settings: settings);
      case '/2':
        return MaterialPageRoute(builder: (_) => ScreenTwo(), settings: settings);
      default:
        return _errorRoute();
    }
  }

  static Route<dynamic> _errorRoute() {
    return MaterialPageRoute(builder: (_) {
      return Scaffold(
        appBar: AppBar(
          title: Text('Error'),
        ),
        body: Center(
          child: Text('ERROR'),
        ),
      );
    });
  }
}

class ScreenOne extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
    );
  }
}

class ScreenTwo extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.yellow,
    );
  }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...