How to know if a page is open/added to Navigator stack?
Asked Answered
C

2

9

I have three pages each one is a StatefulWidget put into separate dart files named:

welcome.dart
page_01.dart
page_02.dart

I open each page using pushNamed function of Navigator like so:

Navigator.of(context).pushNamed('/pageName');

this is made possible using custom RouteGenerator added to my app main MaterialApp widget.

Lets say I open welcome page, then page_01 then page_02 in this order. now I am looking at page_02 which is at the top of Navigation stack. I want to know if page_01 is open/added to Navigation stack and its index number, which in this case should have index of 1.

How to know if a page is open in navigation stack and get its index number ?

Closed answered 18/12, 2019 at 23:24 Comment(0)
M
12

The state class of Navigator holds a list of widgets named List<Route<dynamic>> _history.

Since this value is kept private and there is no public getter provided, we can not find what is the status of pushed widgets at any given moment.

However, NavigatorState does provide some getters to know the status of the extreme ends of _history:

  1. bool get isCurrent // if the current widget/route is at the top of the stack
  2. bool get isActive // if the current widget/route is on the navigator
  3. bool get isFirst // if the current widget/route is at the bottom of the stack

Since none of them takes any widget/route as parameters these getters only use this to produce results for each status queries. There is no way we can get information about widgets that are in the stack but are not being rendered at the moment of the query.

I am afraid I couldn't find any other details to get more about status of other routes.

I have referred to navigator.dart file for these details since most of the properties are kept private, online API documentation is not helpful.

If somebody can come up with more details, just let me know. :D

Margaretamargarete answered 19/12, 2019 at 2:11 Comment(2)
Hello! Just guessing... how or where to get the NavigationState? Thanks!Flagelliform
If you pass a key to the Navigator widget, then you can call key.currentStateLandre
A
0

You can use approach with extending Navigator Observer. Observer will have method for check if page in route. In my example I use Get lib:

  1. Extend navigator observer:
    class YourRouteObserver extends RouteObserver<PageRoute<dynamic>> {
      static final List<Route> routeStack = [];
    
      @override
      void didPush(Route route, Route? previousRoute) {
        routeStack.add(route);
        super.didPush(route, previousRoute);
      }
    
      @override
      void didPop(Route route, Route? previousRoute) {
        routeStack.remove(route);
        super.didPop(route, previousRoute);
      }
    
      @override
      void didRemove(Route route, Route? previousRoute) {
        routeStack.remove(route);
        super.didRemove(route, previousRoute);
      }
    
      @override
      void didReplace({Route? newRoute, Route? oldRoute}) {
        final index = routeStack.indexOf(oldRoute!);
        if (index != -1) {
          routeStack[index] = newRoute!;
        } else {
          routeStack.add(newRoute!);
        }
        super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
      }
    
      static bool containsRoute(String routeName) {
        return routeStack.any((route) => route.settings.name == routeName);
      }
    }
  1. Add observer to your app:
    void main() {
      final routeObserver = YourRouteObserver();
    
      runApp(
        GetMaterialApp(
          getPages: [
            GetPage(name: RouteName.yourPage, page: () => const YourPage()),
          ],
          navigatorObservers: [routeObserver],
        ),
      );
    }

2.1. RouteName just abstract class with Strings, but remember to use / in beginning of name:

abstract class RouteName {
  static const yourPage = '/your-page';
}
  1. Open page by name: onTap: () => Get.toNamed(RouteName.yourPage),

  2. Check if page in stack: AppRouteObserver.containsRoute(RouteName.yourPage)

Arcturus answered 20/6 at 4:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.