Skip to content

Instantly share code, notes, and snippets.

@shivanchalaeologic
Last active August 11, 2020 13:41
Show Gist options
  • Save shivanchalaeologic/447fd6290fbb9d4e3d7970853c6cf4ff to your computer and use it in GitHub Desktop.
Save shivanchalaeologic/447fd6290fbb9d4e3d7970853c6cf4ff to your computer and use it in GitHub Desktop.
/// A [Navigator] observer that notifies [RouteAware]s 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. This is for example
/// useful to keep track of page transitions, e.g. a `RouteObserver<PageRoute>`
/// will inform subscribed [RouteAware]s whenever the user navigates away from
/// the current page route to another page route.
///
/// To be informed about route changes of any type, consider instantiating a
/// `RouteObserver<Route>`.
///
/// ## Type arguments
///
/// When using more aggressive
/// [lints](http://dart-lang.github.io/linter/lints/), in particular lints such
/// as `always_specify_types`, the Dart analyzer will require that certain types
/// be given with their type arguments. Since the [Route] class and its
/// subclasses have a type argument, this includes the arguments passed to this
/// class. Consider using `dynamic` to specify the entire class of routes rather
/// than only specific subtypes. For example, to watch for all [PageRoute]
/// variants, the `RouteObserver<PageRoute<dynamic>>` type may be used.
///
/// {@tool snippet}
///
/// To make a [StatefulWidget] aware of its current [Route] state, implement
/// [RouteAware] in its [State] and subscribe it to a [RouteObserver]:
///
class RouteObserver<R extends Route<dynamic>> extends NavigatorObserver {
final Map<R, Set<RouteAware>> _listeners = <R, Set<RouteAware>>{};
/// Subscribe [routeAware] to be informed about changes to [route].
///
/// Going forward, [routeAware] will be informed about qualifying changes
/// to [route], e.g. when [route] is covered by another route or when [route]
/// is popped off the [Navigator] stack.
void subscribe(RouteAware routeAware, R route) {
assert(routeAware != null);
assert(route != null);
final Set<RouteAware> subscribers = _listeners.putIfAbsent(route, () => <RouteAware>{});
if (subscribers.add(routeAware)) {
routeAware.didPush();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment