Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter - How the NavigatorObserver class works?

Tags:

flutter

dart

I'm trying to detect when the navigator performs the basic operations (push and pop), I found that the class to achieve this is with the NavigatorObserver class, but I can't find an example on how it works.

I already tried implements the interface:

class MyClassState extends State<MyClass> with NavigatorObserver{

    ....

    @override
    void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
        print('This is never get called');
    }

    @override
    void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
        print('This is never get called');
    }
}

Of course I'm calling Navigator.of(context).push(...); But the override methods, never get called.

I suspect the binding with the navigator is missing, but I'm not sure.

Any suggestions?

Thanks in advance!

EDIT:

I think what I want to do is very simple but I can't figure out how to do it.

I have a page A that pushes page B.

On page B I have a periodic timer that must be on there (on page B).

All what I want to do is to cancel the timer with timer.cancel() when the page B get popped out (with back button on Android or back button in appbar), since when the page B get popped out the timer still executing even if the page B has gone.

  • I can't pass the timer as param with the Navigator.pop() since I don't handle the back buttons (the one in the appbar and the Android back button).

EDIT 2:

-I found a way that solves the problem, what I did was cancel the timer on the

@override
void dispose() {
  timer.cancel();
  super.dispose();
}

method. But I'm not sure if this is the best way to accomplish it.

NOTE:

With this workaround the timer still executing if I press the Home button or open the multitask on Android, and when go back to the app this are restarted but again the timer still executing its code.

like image 852
SaloGala Avatar asked Sep 11 '17 23:09

SaloGala


People also ask

How do you use Route observer in Flutter?

RouteObserver<R extends Route> class Null safety A Navigator observer that notifies RouteAwares of changes to the state of their Route. RouteObserver informs subscribers whenever a route of type R is pushed on top of their own route of type R or popped from it.

How does Navigator push work?

Navigator. push() method pushes the given route onto the stack of routes which is maintained by Navigator class. Now to get this route, we can use MaterialPageRoute or we can create our own route.

What is ModalRoute in Flutter?

A route that blocks interaction with previous routes. ModalRoutes cover the entire Navigator. They are not necessarily opaque, however; for example, a pop-up menu uses a ModalRoute but only shows the menu in a small box overlapping the previous route. The T type argument is the return value of the route.

What is MaterialPageRoute in Flutter?

MaterialPageRoute<T> class Null safety. A modal route that replaces the entire screen with a platform-adaptive transition. For Android, the entrance transition for the page zooms in and fades in while the exiting page zooms out and fades out. The exit transition is similar, but in reverse.


2 Answers

Most of the time you don't need to implement NavigatorObserver. See this other StackOverflow answer explaining how to use push and pop to pass information between routes. In the use case you've described, you should addListener to an AnimationController, using the TickerProviderStateMixin to obtain a suitable vsync object. This ensures that your callback will not fire when the app is suspended or after your State is disposed. (Instead of addListener, you could use an AnimatedBuilder or AnimatedWidget the primary purpose of your callback is to rebuild a section of the widget tree.)

The main time when you'd want a NavigatorObserver is if you're using a plugin like Firebase Analytics. You can see an example usage in the plugins repo. You pass the NavigatorObserver in the navigatorObservers argument to the MaterialApp constructor:

static FirebaseAnalyticsObserver observer =
  new FirebaseAnalyticsObserver(analytics: analytics);
...
return new MaterialApp(
  navigatorObservers: <NavigatorObserver>[observer],
  ...
);

It is unusual to have a State that implements NavigatorObserver because your MaterialApp should be near the top of the widget hierarchy. At the time you're constructing it, most State objects won't exist yet so you'll have a hard time putting them into the navigatorObservers array. You might instead use a class that isn't a State. If necessary, you can use GlobalKey<MyClassState> to find the State that needs to be notified (but if you're doing this, there might be an easier way to accomplish what you want).

like image 148
Collin Jackson Avatar answered Oct 31 '22 19:10

Collin Jackson


// Register the RouteObserver as a navigation observer.
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
void main() {
  runApp(MaterialApp(
    home: Container(),
    navigatorObservers: [routeObserver],
  ));
}

class RouteAwareWidget extends StatefulWidget {
  State<RouteAwareWidget> createState() => RouteAwareWidgetState();
}

// Implement RouteAware in a widget's state and subscribe it to the RouteObserver.
class RouteAwareWidgetState extends State<RouteAwareWidget> with RouteAware {

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    routeObserver.subscribe(this, ModalRoute.of(context));
  }

  @override
  void dispose() {
    routeObserver.unsubscribe(this);
    super.dispose();
  }

  @override
  void didPush() {
    // Route was pushed onto navigator and is now topmost route.
  }

  @override
  void didPopNext() {
    // Covering route was popped off the navigator.
  }

  @override
  Widget build(BuildContext context) => Container();

}

This is a more detailed help guide. https://medium.com/flutter-community/how-to-track-screen-transitions-in-flutter-with-routeobserver-733984a90dea

like image 41
Ares Avatar answered Oct 31 '22 21:10

Ares