FilledStacks / flutter-tutorials

The repo contains the source code for all the tutorials on the FilledStacks Youtube channel.
MIT License
4.75k stars 1.76k forks source link

037 - Advanced URL navigation Navigator issue #35

Closed ibosev closed 4 years ago

ibosev commented 4 years ago

Hi, there is no template to report issues so I will jump right to it. With the latest changes and with adding navigatorKey to the MaterialApp, now we cannot easily close scaffold drawer.

Most users want to close the drawer onTap and be redirected. In the latest code if one tries to close the drawer like this:

    return GestureDetector(
      onTap: () {
        // DON'T EVER USE A SERVICE DIRECTLY IN THE UI TO CHANGE ANY KIND OF STATE
        // SERVICES SHOULD ONLY BE USED FROM A VIEWMODEL

        // NEW LINE ADDED TO CLOSE DRAWER
        Navigator.of(context).pop();
        locator<NavigationService>().navigateTo(navigationPath);
      },

it will end up with the following error:

Navigator operation requested with a context that does not include a Navigator.

Can you please direct me to a solution of this issue. There is no exposed DrawerController and I can only open the drawer programatically and I am not aware of other solution to close the drawer besides the above-mentioned one (link below): https://api.flutter.dev/flutter/material/Drawer-class.html

FilledStacks commented 4 years ago

One solution is to add a parameter to the navigateTo function true or false, called popBeforeNavigate. Inside you can check if it’s true and then pop on the key before you navigate. From: Ivaylo Bosevmailto:notifications@github.com Sent: Thursday, 16 January 2020 20:27 To: FilledStacks/flutter-tutorialsmailto:flutter-tutorials@noreply.github.com Cc: Subscribedmailto:subscribed@noreply.github.com Subject: [FilledStacks/flutter-tutorials] 037 - Advanced URL navigation Navigator issue (#35)

Hi, there is no template to report issues so I will jump right to it. With the latest changes and with adding navigatorKey to the MaterialApp, now we cannot easily close scaffold drawer.

Most users want to close the drawer onTap and be redirected. In the latest code if one tries to close the drawer like this:

return GestureDetector(

  onTap: () {

    // DON'T EVER USE A SERVICE DIRECTLY IN THE UI TO CHANGE ANY KIND OF STATE

    // SERVICES SHOULD ONLY BE USED FROM A VIEWMODEL

    // NEW LINE ADDED TO CLOSE DRAWER

    Navigator.of(context).pop();

    locator<NavigationService>().navigateTo(navigationPath);

  },

it will end up with the following error:

Navigator operation requested with a context that does not include a Navigator.

Can you please direct me to a solution of this issue. There is no exposed DrawerController and I can only open the drawer programatically and I am not aware of other solution to close the drawer besides the above-mentioned one (link below): https://api.flutter.dev/flutter/material/Drawer-class.html

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHubhttps://github.com/FilledStacks/flutter-tutorials/issues/35?email_source=notifications&email_token=AA3M72VST2MZK3BBPBNUADLQ6CRIXA5CNFSM4KHYTZV2YY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4IGXIQWQ, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AA3M72UPEFCEFA7NEDYLBH3Q6CRIXANCNFSM4KHYTZVQ.

ibosev commented 4 years ago

Unfortunately this does not solve it for me:

 locator<NavigationService>()
            .navigateTo(navigationPath, popBeforeNavigate: true);
  Future<dynamic> navigateTo(String routeName,
      {bool popBeforeNavigate = false}) {
    if (popBeforeNavigate) {
      return navigatorKey.currentState.popAndPushNamed(routeName);
    }
    return navigatorKey.currentState.pushNamed(routeName);
  }

Now there is no error in the console, but the drawer still does not close. My suggestion is that the drawer widget has different navigator state for some reason and the issue came up when we added navigator key directly to the MaterialApp.

I forgot to mention that I tried this before I opened the ticket as well:

        Navigator.of(locator<NavigationService>().navigatorKey.currentContext).pop();
ptrckdev commented 4 years ago

it seems like the drawer state is not part of the navigationKey.

@ibosev have you found a work around?

Thanks for posting this issue, I would have gone mad without it by now 😂

ptrckdev commented 4 years ago

So what I am doing now until I find a better solution, or have to find one because this fix might break somethings down the line:

To programmatically open the drawer I needed to supply a key to the Scaffold. Now if I need to close the Drawer I still cannot use the context in the NavbarItem. Instead I use the scaffoldKey to and call openEndDrawer() on it. What it does is first close the Drawer and then open a EndDrawer. But aslong as I don't have an EndDrawer I can use this method to close my Drawer programmatically.

Dirty hack, I know, but it is the only solution I can come up with for now.

Cheers, Patrick

ibosev commented 4 years ago

OMG, @ptrckdev

I would have never thought of this. It is a dirty hack indeed, but it works. Flutter dev team should give us a tool to handle drawers more efficiently. Until then we are should think of workarounds :)

FilledStacks commented 4 years ago

@ptrckdev that is how I do it in my mobile flutter apps as well. Usually the drawer is stacked as a navigation path so a pop would work. I wonder why it doesn't in this case.

Thanks for updating with a solution