Flutter: How to automatically trigger a function when a route was pushed on to the stack?

Viewed 2385

I want to trigger automatically trigger a function when a screen is pushed on to the stack. I have been doing some research and I think this could be achieved by extending WidgetsBindingObserver class.

Once I have extended it, calling didPushRoute method should be the way to go. So the first thing is to ask if I could be right with this approach.

The second question, and request if you will, would be to ask for a specific implementation or example of this, if it’s the case that the mentioned approach is correct. Doing the same when popping a route is another thing I want, but I think it is on the same line. The main idea of this approach would be to make specific things happen automatically when navigating.

I am looking for something that always happen when the current route / or a specific stateless or stateful gets covered by another screen, rather than manually executing a function with navigator, otherwise I would need to do this for every new push I want to do.

Thanks in advance for the feedback and let me know if have to explain something deeper of what I am trying to achieve.

3 Answers

When you navigate from Screen 1 to Screen 2, you use the push method. The push method returns a Future object. You can use the then method of Future to execute your code after Screen 2 was popped from the navigation stack.

Navigator.of(context)
  .push(MaterialPageRoute(
   builder: (context) => Screen2(),
  ))
  .then((value) {
    // you can do what you need here
    // setState etc.
  });

https://stackoverflow.com/a/61644205/13252751

After trying lots of methods to achieve what I wanted, I realized that the comments above telling the way to go would be with a route observer are right. So here I am posting the code that helped me achieve what I wanted. This code makes reference to: Flutter - How the NavigatorObserver class works?

// 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();

}

For me concretely was this method that helped to achieve the desired behavior:

  @override
  void didPushNext() {
    // TODO: implement didPushNext
    super.didPushNext();
  }

You can look at the official documents for passing data or invoke function with navigator callbacks. As a workaround you can also insert some function before push and call it before pop.

Related