Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

flutter

dart

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?

like image 237
iDecode Avatar asked Feb 22 '20 06:02

iDecode


People also ask

What is the use of push function of Navigator?

The push() method adds a Route to the stack of routes managed by the Navigator . Where does the Route come from? You can create your own, or use a MaterialPageRoute , which is useful because it transitions to the new route using a platform-specific animation.

What is navigator in Flutter how is it used?

In Flutter these elements are called routes and they're managed by a Navigator widget. The navigator manages a stack of Route objects and provides two ways for managing the stack, the declarative API Navigator. pages or imperative API Navigator. push and Navigator.

What is navigator of context?

Navigator. of(context) has optional parameters, if rootNavigator is set to true, the NavigatorState from the furthest is given instead. static NavigatorState of( BuildContext context, { bool rootNavigator = false, bool nullOk = false, }) Navigator. push(context, route) is a static method and do both at the same time.

What is navigator key in Flutter?

navigatorKey. A key to use when building the Navigator. If a navigatorKey is specified, the Navigator can be directly manipulated without first obtaining it from a BuildContext via Navigator. of: from the navigatorKey, use the GlobalKey. currentState getter.


2 Answers

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);
          },
        ),
      ),
    );
  }
}
like image 146
chunhunghan Avatar answered Oct 24 '22 03:10

chunhunghan


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

like image 42
ehsaneha Avatar answered Oct 24 '22 04:10

ehsaneha