iDecode
iDecode

Reputation: 28986

What is the use of `rootNavigator` in Navigator.of(context, rootNavigator: true).push();

What's the difference between

Navigator.of(context).pushNamed("/route");

and

Navigator.of(context, rootNavigator: true).pushNamed("/route");

More importantly, what's the use of setting rootNavigator: true on Navigator class, I read docs but they aren't quite clear. Can anyone explain the difference properly?

Upvotes: 24

Views: 22550

Answers (2)

ehsaneha
ehsaneha

Reputation: 1843

If your app has nested navigators this parameter comes in handy when you want to call the root navigator not it's nested navigators ... please consider the image bellow ... in this example we are inside the page 2 and we want the page 3 to be the rootNavigator's child (because for example we want to ignore the bottomNavigationBar that is in MainPage)... in this example if you don't set the rootNavigator = true and you push the page 3 it will be the nestedNavigator's child (So the BottomNavigationBar of the MainPage's will be still visible). enter image description here

Upvotes: 20

chunhunghan
chunhunghan

Reputation: 54397

You can copy paste run full code below
There is a root Navigator above tab navigation
This demo shows open(Navigator.push) a full screen dialog (fullscreenDialog: true) with rootNavigator true/false

picture
rootNavigator = true , fullscreenDialog take all screen and above tab
rootNavigator = false, fullscreenDialog take tab size and inside tab, you can switch between Home and Support tab and see fullscreenDialog is still there

enter image description here

working demo

enter image description here

code snippet

  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(),
          ),
        );
      },
    ),
  ),

full code

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);
          },
        ),
      ),
    );
  }
}

Upvotes: 28

Related Questions