flutter - router onRouteGenerated:仅在子小部件中,而不是在材质应用小部件中设置
问题描述
我想要一个底部导航栏并使用命名路由(主要用于颤振网络)。
因此,我总是需要标签栏脚手架作为基础,并有一个导航器小部件作为其内容的主体。这工作正常。问题是,如果我移动到第二个选项卡并在 Flutter Web 中重新加载应用程序,我会收到以下错误消息:
══╡ 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,
);
}
}
解决方案
推荐阅读
- javascript - 对象不支持 IE11 中的属性或方法“forEach”
- ruby-on-rails - 尝试将 :confirmable 添加到 Rails 中的用户时出现无效的交付方法错误
- java - 无法使用 Selenium Java 在网页上输入文本以输入类型
- objective-c - 如何在 Objective-C 中将 long 转换为 NSString?
- c - 为什么对具有灵活数组成员的结构的初始化无效但对固定大小的数组成员有效?
- excel - 将 vbYesNo 输入框上的按钮更改为自定义选项
- python - 使用两个索引访问 pyomo 变量
- java - 为什么 C++ 使用指针指向链表中的下一个节点,而 C# 或 Java 等语言只使用类 Node 的名称?
- html - 如何在 chrome/Firefox 上自动播放音频
- android - kotlin 惰性初始化属性不能在 init 块中修改