background

Navigator.of(context).push(MaterialPageRoute(builder: (context){
          return DemoPage();
        }));
Copy the code

In daily project development, we generally use the above method to push a new page, using Navigator. Of (context) for push or pop operations.

Disadvantages: Context must be passed in order to use navigator.of (context) to get the NavigatorState object before push or pop.

So if I want to push a new page anywhere in the project, and I don’t want to get the context, then I want to do a context-free jump.

The solution

No context jump, essentially we don’t have to pass the context argument every time, and then use some operation directly to get the current NavigatorState.

Scenario 1: Use GlobalKey

  • In Flutter, the GolbalKey is used to retrieve the State object of the corresponding Widget. So, here, we can get the NavigatorState object from a GlobalKey.
  • WidgetsApp is wrapped in the MaterialApp, while WidgetsApp wraps the Navigator and exposes the Navigator’s key property as the navigatorKey. So, we can set the navigatorKey and use that key to get the NavigatorState object.

Here post the relevant source code, specific we can go to see the source code. MaterialApp class:

WidgetsApp class: The navigatorKey we defined is the final key passed to the Navigator, so we can get the NavigatorState object outside using key.currentState().

class _WidgetsAppState extends State<WidgetsApp> implements WidgetsBindingObserver {

 GlobalKey<NavigatorState> _navigator;

  void _updateNavigator() {
    _navigator = widget.navigatorKey ?? GlobalObjectKey<NavigatorState>(this);
  }
  
  @override
  Widget build(BuildContext context) {
    Widget navigator;
    if(_navigator ! = null) { navigator = Navigator( key: _navigator, initialRoute: WidgetsBinding.instance.window.defaultRouteName ! = Navigator.defaultRouteName ? WidgetsBinding.instance.window.defaultRouteName : widget.initialRoute ?? WidgetsBinding.instance.window.defaultRouteName, onGenerateRoute: _onGenerateRoute, onUnknownRoute: _onUnknownRoute, observers: widget.navigatorObservers, ); }}Copy the code

Simple code implementation

  1. Define a GlobalKey< NavigatorState> object
  static GlobalKey<NavigatorState> navigatorKey=GlobalKey();
Copy the code
  1. When creating the MaterialApp object, assign the navigatorKey to the MaterialApp.
MaterialApp(
          navigatorKey: Router.navigatorKey,
)
Copy the code
  1. Use GlobalKey to get NavigatorState objects anywhere
navigatorKey.currentState.pushNamed("/login");
Copy the code

Plan 2: Use NavigatorObserver

  • NavigatorObserver is used to monitor changes in the Navigator. For example, when pushing a new page, the Navigator listens for changes in NavigatorState and calls back the didPush () method.

Note: NavigatorObserver defines a NavigatorState object, so you can customize NavigatorObserver and use the navigator object directly to do page push or pop operations. So we don’t have to use the context to get the navigatorState object ourselves.

  • The MaterialApp class provides navigatorObservers with a property that allows you to customize navigatorObservers to listen for changes in the Navigator.
  • The NavigatorState class, when executing the instState object, assigns itself to the _navigator of all the monitored observers.

Simple code implementation

  1. Custom NavigatorObserver.
class CustomNavigatorObserver extends NavigatorObserver{
  static CustomNavigatorObserver _instance;

  static CustomNavigatorObserver getInstance() {
    if (_instance == null) {
      _instance = CustomNavigatorObserver();
    }
    return_instance; }}Copy the code
  1. When creating the MaterialApp object, assign the CustomNavigatorObserver value to the MaterialApp
MaterialApp(
          navigatorObservers: [CustomNavigatorObserver()],
)
Copy the code
  1. Use the CustomNavigatorObserver for page manipulation anywhere
CustomNavigatorObserver.getInstance().navigator.pushNamed("/login");
Copy the code

Refer to the article

In fact, this kind of article digging gold above also have, write this article, mainly do their own summary.

Links to the big guys’ articles:

Flutter | through the ServiceLocator context navigation is realized

Route chapter of Flutter online Project