1

I am having the following setup:

MaterialApp(home:SplashScreen)


SplashScreen(
///do some auth checks then
Navigator.of(context).push( MaterialPageRoute(
                builder: (_) =>  StateInheritedWidget(
                  user: userData,
                  child:  HomePage(),

                )))
)

Then in my HomePage I have a FAB that pushes a new route. This new route has no access to the context of my inherited widget.

Is it impossible to get the context of an InheritedWidget in new routes, or is there a way to solve this issue ?


Update

This is my MaterialApp's builder property

    builder: (context,child){
///Doing some auth stuff here
        return new StateInheritedWidget(
          user: userData,
                      child: userData==null?const SplashScreen(child: const LoginPage(),): 
                      const SplashScreen(child: const HomePage(),),

        );
      },

My SplashScreen build method:

return !_load? new Scaffold(
      body: new Center(
        child: new Text('Splash'),
      ),
    ):this.widget.child;

These are the error I get.

The first one seems to be related to the Drawer in my HomePage:

I/flutter (12688): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (12688): The following assertion was thrown building Tooltip("Open navigation menu", vertical offset: 24.0,
I/flutter (12688): position: below, dirty, state: _TooltipState#44ae9(ticker inactive)):
I/flutter (12688): No Overlay widget found.
I/flutter (12688): Tooltip widgets require an Overlay widget ancestor for correct operation.
I/flutter (12688): The most common way to add an Overlay to an application is to include a MaterialApp or Navigator
I/flutter (12688): widget in the runApp() call.
I/flutter (12688): The specific widget that failed to find an overlay was:
I/flutter (12688):   Tooltip("Open navigation menu", vertical offset: 24.0, position: below)
I/flutter (12688):

The second exception appears when I click on FAB (Navigator.push)

I/flutter (12688): Another exception was thrown: Navigator operation requested with a context that does not include a Navigator.
Shady Aziza
  • 50,824
  • 20
  • 115
  • 113

1 Answers1

7

No. That's not possible (or at least not recommended).

The problem lies in the fact that your inheritedWidget shouldn't be inside the route but instead above the route. Usually above MaterialApp

But I want my Authentification to be able to push a login screen, I can't put it above MaterialApp !

Which is why I said usually. :D

Authentification is one of these exceptions. You may want your authent layer to access the Navigator. But still want to share that authent layer with all routes.

This is where an useful property of MaterialApp is used : builder

Builder, when passed, will be used to insert any kind of widget right above your routes. But still be after Navigator so that you can still push new routes when needed.

In the end, you'd have

new MaterialApp(
  builder: (context, child) {
    return new MyAuthent(child: child);
  },
  ...
  // home: SplashSceen ?
);

This will most likely requires a refactor on your end. But that's the proper way to achieve this.

Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
  • Is MyAuthent in your example the inherited widget ? and does this mean I do not need the home property of MaterialApp , I can just return the splash widget instead as MyAuthent child ? – Shady Aziza Mar 17 '18 at 08:58
  • Can you clarify this please, I am not sure what I am doing is the right thing, I am getting this error: `E/flutter (11514): Navigator operation requested with a context that does not include a Navigator. E/flutter (11514): The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.` – Shady Aziza Mar 17 '18 at 08:59
  • I have updated the question to show you my changes and the exact errors I am getting – Shady Aziza Mar 17 '18 at 09:20
  • That's not what I told you to do duh ! `builder` should only wrap `child`. Not override it. Or you'll break the whole `Navigator` thing. But yeah, MyAuthent is an inherited widget. Or a stateful widget that instantiate an InheritedWidget. – Rémi Rousselet Mar 17 '18 at 15:08
  • Your builder never use `child` property. `child` is your actual view. – Rémi Rousselet Mar 17 '18 at 15:11
  • Ops, ye I see. but where do I get this child from ? Can you mirror my use case to your example please ? – Shady Aziza Mar 17 '18 at 15:12
  • It's passed as parameter to `builder`. That's the current pushed route (or home by default). – Rémi Rousselet Mar 17 '18 at 15:13
  • 1
    I still do not understand how it can be integrated in my example. – Shady Aziza Mar 17 '18 at 15:20