Commit 0e976372 authored by Jason Simmons's avatar Jason Simmons Committed by GitHub

Implement a pushRoute service to satisfy the FlutterView.pushRoute API (#10415)

Fixes https://github.com/flutter/flutter/issues/10399
parent 1b5b929c
......@@ -166,6 +166,15 @@ class _WidgetsAppState extends State<WidgetsApp> implements WidgetsBindingObserv
return await navigator.maybePop();
}
@override
Future<bool> didPushRoute(String route) async {
assert(mounted);
final NavigatorState navigator = _navigator.currentState;
assert(navigator != null);
navigator.pushNamed(route);
return true;
}
@override
void didChangeMetrics() {
setState(() {
......
......@@ -37,6 +37,14 @@ abstract class WidgetsBindingObserver {
/// its current route if possible.
Future<bool> didPopRoute() => new Future<bool>.value(false);
/// Called when the host tells the app to push a new route onto the
/// navigator.
///
/// Observers are expected to return true if they were able to
/// handle the notification. Observers are notified in registration
/// order until one returns true.
Future<bool> didPushRoute(String route) => new Future<bool>.value(false);
/// Called when the application's dimensions change. For example,
/// when a phone is rotated.
void didChangeMetrics() { }
......@@ -198,10 +206,23 @@ abstract class WidgetsBinding extends BindingBase implements GestureBinding, Ren
SystemNavigator.pop();
}
Future<dynamic> _handleNavigationInvocation(MethodCall methodCall) async {
if (methodCall.method == 'popRoute')
handlePopRoute();
// TODO(abarth): Handle 'pushRoute'.
/// Called when the host tells the app to push a new route onto the
/// navigator.
Future<Null> handlePushRoute(String route) async {
for (WidgetsBindingObserver observer in new List<WidgetsBindingObserver>.from(_observers)) {
if (await observer.didPushRoute(route))
return;
}
}
Future<dynamic> _handleNavigationInvocation(MethodCall methodCall) {
switch (methodCall.method) {
case 'popRoute':
return handlePopRoute();
case 'pushRoute':
return handlePushRoute(methodCall.arguments);
}
return new Future<Null>.value();
}
/// Called when the application lifecycle state changes.
......
......@@ -26,6 +26,16 @@ class AppLifecycleStateObserver extends WidgetsBindingObserver {
}
}
class PushRouteObserver extends WidgetsBindingObserver {
String pushedRoute;
@override
Future<bool> didPushRoute(String route) async {
pushedRoute = route;
return true;
}
}
void main() {
setUp(() {
WidgetsFlutterBinding.ensureInitialized();
......@@ -61,4 +71,17 @@ void main() {
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) {});
expect(observer.lifecycleState, AppLifecycleState.suspending);
});
testWidgets('didPushRoute callback', (WidgetTester tester) async {
final PushRouteObserver observer = new PushRouteObserver();
WidgetsBinding.instance.addObserver(observer);
final String testRouteName = 'testRouteName';
final ByteData message = const JSONMethodCodec().encodeMethodCall(
new MethodCall('pushRoute', testRouteName));
await BinaryMessages.handlePlatformMessage('flutter/navigation', message, (_) {});
expect(observer.pushedRoute, testRouteName);
WidgetsBinding.instance.removeObserver(observer);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment