mirror of
https://github.com/flutter/flutter
synced 2024-10-13 19:52:53 +00:00
RouteObserver supports multiple RouteAware per Route. (#13757)
Unsubscribe should remove RouteAware for all routes.
This commit is contained in:
parent
107c812f64
commit
467daba419
|
@ -1116,7 +1116,7 @@ abstract class PopupRoute<T> extends ModalRoute<T> {
|
|||
/// }
|
||||
/// ```
|
||||
class RouteObserver<T extends Route<dynamic>> extends NavigatorObserver {
|
||||
final Map<T, RouteAware> _listeners = <T, RouteAware>{};
|
||||
final Map<T, Set<RouteAware>> _listeners = <T, Set<RouteAware>>{};
|
||||
|
||||
/// Subscribe [routeAware] to be informed about changes to [route].
|
||||
///
|
||||
|
@ -1126,32 +1126,55 @@ class RouteObserver<T extends Route<dynamic>> extends NavigatorObserver {
|
|||
void subscribe(RouteAware routeAware, T route) {
|
||||
assert(routeAware != null);
|
||||
assert(route != null);
|
||||
if (!_listeners.containsKey(route)) {
|
||||
final Set<RouteAware> subscribers = _listeners.putIfAbsent(route, () => new Set<RouteAware>());
|
||||
if (subscribers.add(routeAware)) {
|
||||
routeAware.didPush();
|
||||
_listeners[route] = routeAware;
|
||||
}
|
||||
}
|
||||
|
||||
/// Unsubscribe [routeAware].
|
||||
///
|
||||
/// [routeAware] is no longer informed about changes to its route.
|
||||
/// [routeAware] is no longer informed about changes to its route. If the given argument was
|
||||
/// subscribed to multiple types, this will unregister it (once) from each type.
|
||||
void unsubscribe(RouteAware routeAware) {
|
||||
assert(routeAware != null);
|
||||
_listeners.remove(routeAware);
|
||||
for (T route in _listeners.keys) {
|
||||
final Set<RouteAware> subscribers = _listeners[route];
|
||||
subscribers?.remove(routeAware);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
|
||||
if (route is T && previousRoute is T) {
|
||||
_listeners[previousRoute]?.didPopNext();
|
||||
_listeners[route]?.didPop();
|
||||
final List<RouteAware> previousSubscribers = _listeners[previousRoute]?.toList();
|
||||
|
||||
if (previousSubscribers != null) {
|
||||
for (RouteAware routeAware in previousSubscribers) {
|
||||
routeAware.didPopNext();
|
||||
}
|
||||
}
|
||||
|
||||
final List<RouteAware> subscribers = _listeners[route]?.toList();
|
||||
|
||||
if (subscribers != null) {
|
||||
for (RouteAware routeAware in subscribers) {
|
||||
routeAware.didPop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
|
||||
if (route is T && previousRoute is T) {
|
||||
_listeners[previousRoute]?.didPushNext();
|
||||
final Set<RouteAware> previousSubscribers = _listeners[previousRoute];
|
||||
|
||||
if (previousSubscribers != null) {
|
||||
for (RouteAware routeAware in previousSubscribers) {
|
||||
routeAware.didPushNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -453,6 +453,31 @@ void main() {
|
|||
observer.didPop(route, pageRoute);
|
||||
verifyNoMoreInteractions(pageRouteAware);
|
||||
});
|
||||
|
||||
test('does not call listeners when already subscribed', () {
|
||||
final RouteObserver<PageRoute<dynamic>> observer = new RouteObserver<PageRoute<dynamic>>();
|
||||
final RouteAware pageRouteAware = new MockRouteAware();
|
||||
final MockPageRoute pageRoute = new MockPageRoute();
|
||||
observer.subscribe(pageRouteAware, pageRoute);
|
||||
observer.subscribe(pageRouteAware, pageRoute);
|
||||
verify(pageRouteAware.didPush()).called(1);
|
||||
});
|
||||
|
||||
test('does not call listeners when unsubscribed', () {
|
||||
final RouteObserver<PageRoute<dynamic>> observer = new RouteObserver<PageRoute<dynamic>>();
|
||||
final RouteAware pageRouteAware = new MockRouteAware();
|
||||
final MockPageRoute pageRoute = new MockPageRoute();
|
||||
final MockPageRoute nextPageRoute = new MockPageRoute();
|
||||
observer.subscribe(pageRouteAware, pageRoute);
|
||||
observer.subscribe(pageRouteAware, nextPageRoute);
|
||||
verify(pageRouteAware.didPush()).called(2);
|
||||
|
||||
observer.unsubscribe(pageRouteAware);
|
||||
|
||||
observer.didPush(nextPageRoute, pageRoute);
|
||||
observer.didPop(nextPageRoute, pageRoute);
|
||||
verifyNoMoreInteractions(pageRouteAware);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue