Я хочу иметь нижнюю панель навигации и использовать именованные маршруты (в основном, для веб-флаттера).
Поэтому мне всегда нужно скаффолд с панелью вкладок в качестве основы и использование виджета навигатора в качестве его тела для содержание. Это работает нормально. Проблема в том, что если я перехожу на вторую вкладку и перезагружаю приложение в веб-приложении, я получаю следующее сообщение об ошибке:
══╡ 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,
);
}
}