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 ,您可以在HomeSupport 选项卡之间切换,看到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'

Navigator.pop() - 如何传递 `context` 以供导航器读取 -

从另一个文件中调用一个Object