Navigator.of(context, rootNavigator: true).push()中的`rootNavigator`有啥用?
Posted
技术标签:
【中文标题】Navigator.of(context, rootNavigator: true).push()中的`rootNavigator`有啥用?【英文标题】:What is the use of `rootNavigator` in Navigator.of(context, rootNavigator: true).push();Navigator.of(context, rootNavigator: true).push()中的`rootNavigator`有什么用? 【发布时间】:2020-06-06 12:54:47 【问题描述】:有什么区别
Navigator.of(context).pushNamed("/route");
和
Navigator.of(context, rootNavigator: true).pushNamed("/route");
更重要的是,在Navigator
类上设置rootNavigator: true
有什么用,我阅读了文档,但它们不太清楚。谁能正确解释其中的区别?
【问题讨论】:
如果您使用的是嵌套导航器,并且您想从嵌套导航器内部的屏幕导航到***导航器的一部分,那么您必须将 rootNavigator 设置为真的。你可以在这里api.flutter.dev/flutter/widgets/Navigator-class.html阅读更多相关信息。 谢谢,但我想看看它的例子,如果你能展示的话。 【参考方案1】:您可以在下面复制粘贴运行完整代码
标签导航上方有一个root Navigator
这个演示展示了用rootNavigator true/false
打开(Navigator.push
)一个全屏对话框(fullscreenDialog: true
)
图片 rootNavigator
= true
, fullscreenDialog
获取所有屏幕及以上tab
rootNavigator
= false
, fullscreenDialog
获取tab
大小和内部tab
,您可以在Home
和Support
选项卡之间切换,看到fullscreenDialog
仍然存在
工作演示
代码sn-p
Center(
child: CupertinoButton(
child: const Text(
'Push rootNavigator true',
),
onPressed: ()
Navigator.of(context, rootNavigator: true).push(
CupertinoPageRoute<bool>(
fullscreenDialog: true,
builder: (BuildContext context) => Tab3Dialog(),
),
);
,
),
),
Center(
child: CupertinoButton(
child: const Text(
'Push rootNavigator false',
),
onPressed: ()
Navigator.of(context, rootNavigator: false).push(
CupertinoPageRoute<bool>(
fullscreenDialog: true,
builder: (BuildContext context) => Tab3Dialog(),
),
);
,
),
),
完整代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget
// This widget is the root of your application.
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: PawzHome(),
);
class PawzHome extends StatelessWidget
@override
Widget build(BuildContext context)
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.conversation_bubble),
title: Text('Support'),
),
],
),
tabBuilder: (BuildContext context, int index)
switch (index)
case 0:
return CupertinoTabView(
builder: (BuildContext context)
return CupertinoDemoTab1();
,
defaultTitle: 'Colors',
);
break;
case 1:
return CupertinoTabView(
builder: (BuildContext context) => CupertinoDemoTab2(),
defaultTitle: 'Support Chat',
);
break;
return null;
,
);
class CupertinoDemoTab1 extends StatelessWidget
@override
Widget build(BuildContext context)
return CupertinoPageScaffold(
child: CustomScrollView(
slivers: <Widget>[
CupertinoSliverNavigationBar(),
SliverList(
delegate: SliverChildListDelegate([Tab1RowItem()]),
),
],
),
);
class Tab1RowItem extends StatelessWidget
@override
Widget build(BuildContext context)
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: ()
Navigator.of(context).push(CupertinoPageRoute<void>(
title: "Click me",
builder: (BuildContext context) => Tab1ItemPage(),
));
,
child: Padding(padding: EdgeInsets.all(10.0), child: Text("Click me")),
);
class Tab1ItemPage extends StatelessWidget
@override
@override
Widget build(BuildContext context)
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(),
child: Container(
child: Column(
children: <Widget>[
SizedBox(height: 100,),
Center(
child: CupertinoButton(
child: const Text(
'Push rootNavigator true',
),
onPressed: ()
Navigator.of(context, rootNavigator: true).push(
CupertinoPageRoute<bool>(
fullscreenDialog: true,
builder: (BuildContext context) => Tab3Dialog(),
),
);
,
),
),
Center(
child: CupertinoButton(
child: const Text(
'Push rootNavigator false',
),
onPressed: ()
Navigator.of(context, rootNavigator: false).push(
CupertinoPageRoute<bool>(
fullscreenDialog: true,
builder: (BuildContext context) => Tab3Dialog(),
),
);
,
),
),
],
),
));
class CupertinoDemoTab2 extends StatelessWidget
@override
Widget build(BuildContext context)
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(),
child: Container(
child: Center(
child: Text("Tab 2"),
),
));
class Tab3Dialog extends StatelessWidget
@override
Widget build(BuildContext context)
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
leading: CupertinoButton(
onPressed: ()
Navigator.of(context).pop(false);
,
child: Text("Ok"),
),
),
child: Center(
child: CupertinoButton(
color: CupertinoColors.activeBlue,
child: const Text('Sign in'),
onPressed: ()
Navigator.pop(context);
,
),
),
);
【讨论】:
【参考方案2】:如果您的应用有嵌套导航器,当您想要调用根导航器而不是嵌套导航器时,此参数会派上用场……请考虑下图……在此示例中,我们位于第 2 页内,我们想要第 3 页是 rootNavigator 的子 (因为例如我们想忽略 MainPage 中的 bottomNavigationBar)...在这个例子中,如果你没有设置 rootNavigator = true
并且你推送页面3 它将是nestedNavigator 的子(因此MainPage 的BottomNavigationBar 仍然可见)。
【讨论】:
如果您在MainPage
中有bottomNavigationBar
并且您使用嵌套导航器导航到Page3
,则底部导航栏将不可见(在android/ios 中均已测试)。跨度>
以上是关于Navigator.of(context, rootNavigator: true).push()中的`rootNavigator`有啥用?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Navigator.of(context).push(....) 之后临时取消订阅 Stream?
Flutter:如何将 PageRoute Animation 与 Navigator.of(context).pushNamed 结合起来
在showDialog中Flutter Navigator.of(context).pop(),在ios中关闭整个应用程序
查找已停用小部件的祖先是不安全的 => 使用 Riverpod => 使用 "Navigator.of(context).pushReplacementNamed('/page'