onNavigationNotification for *App.router (#142190)

onNavigationNotification was not being passed through when using the router in MaterialApp and CupertinoApp. I believe this was just an oversight on my part when I wrote https://github.com/flutter/flutter/pull/120385. This PR passes them through.

Fixes https://github.com/flutter/flutter/issues/139903

@maRci0002 Would this totally fix your issue https://github.com/flutter/flutter/issues/139903?
This commit is contained in:
Justin McCandless 2024-01-29 14:00:51 -08:00 committed by GitHub
parent 1af09dde12
commit ade8af278f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 100 additions and 1 deletions

View file

@ -547,6 +547,7 @@ class _CupertinoAppState extends State<CupertinoApp> {
routerDelegate: widget.routerDelegate,
routerConfig: widget.routerConfig,
backButtonDispatcher: widget.backButtonDispatcher,
onNavigationNotification: widget.onNavigationNotification,
builder: widget.builder,
title: widget.title,
onGenerateTitle: widget.onGenerateTitle,

View file

@ -1016,6 +1016,7 @@ class _MaterialAppState extends State<MaterialApp> {
routerDelegate: widget.routerDelegate,
routerConfig: widget.routerConfig,
backButtonDispatcher: widget.backButtonDispatcher,
onNavigationNotification: widget.onNavigationNotification,
builder: _materialBuilder,
title: widget.title,
onGenerateTitle: widget.onGenerateTitle,

View file

@ -706,7 +706,12 @@ class WidgetsApp extends StatefulWidget {
/// {@template flutter.widgets.widgetsApp.onNavigationNotification}
/// The callback to use when receiving a [NavigationNotification].
///
/// By default this updates the engine with the navigation status.
/// By default this updates the engine with the navigation status and stops
/// bubbling the notification.
///
/// See also:
///
/// * [NotificationListener.onNotification], which uses this callback.
/// {@endtemplate}
final NotificationListenerCallback<NavigationNotification>? onNavigationNotification;

View file

@ -179,6 +179,52 @@ void main() {
expect(find.text('popped'), findsOneWidget);
});
testWidgets('CupertinoApp.router works with onNavigationNotification', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/139903.
final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider(
initialRouteInformation: RouteInformation(
uri: Uri.parse('initial'),
),
);
addTearDown(provider.dispose);
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) {
return Text(information.uri.toString());
},
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = RouteInformation(
uri: Uri.parse('popped'),
);
return route.didPop(result);
},
);
addTearDown(delegate.dispose);
int navigationCount = 0;
await tester.pumpWidget(CupertinoApp.router(
routeInformationProvider: provider,
routeInformationParser: SimpleRouteInformationParser(),
routerDelegate: delegate,
onNavigationNotification: (NavigationNotification? notification) {
navigationCount += 1;
return true;
},
));
expect(find.text('initial'), findsOneWidget);
expect(navigationCount, greaterThan(0));
final int navigationCountAfterBuild = navigationCount;
// Simulate android back button intent.
final ByteData message = const JSONMethodCodec().encodeMethodCall(const MethodCall('popRoute'));
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
await tester.pumpAndSettle();
expect(find.text('popped'), findsOneWidget);
expect(navigationCount, greaterThan(navigationCountAfterBuild));
});
testWidgets('CupertinoApp.router route information parser is optional', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) {

View file

@ -1118,6 +1118,52 @@ void main() {
expect(find.text('popped'), findsOneWidget);
});
testWidgets('MaterialApp.router works with onNavigationNotification', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/139903.
final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider(
initialRouteInformation: RouteInformation(
uri: Uri.parse('initial'),
),
);
addTearDown(provider.dispose);
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) {
return Text(information.uri.toString());
},
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
delegate.routeInformation = RouteInformation(
uri: Uri.parse('popped'),
);
return route.didPop(result);
},
);
addTearDown(delegate.dispose);
int navigationCount = 0;
await tester.pumpWidget(MaterialApp.router(
routeInformationProvider: provider,
routeInformationParser: SimpleRouteInformationParser(),
routerDelegate: delegate,
onNavigationNotification: (NavigationNotification? notification) {
navigationCount += 1;
return true;
},
));
expect(find.text('initial'), findsOneWidget);
expect(navigationCount, greaterThan(0));
final int navigationCountAfterBuild = navigationCount;
// Simulate android back button intent.
final ByteData message = const JSONMethodCodec().encodeMethodCall(const MethodCall('popRoute'));
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
await tester.pumpAndSettle();
expect(find.text('popped'), findsOneWidget);
expect(navigationCount, greaterThan(navigationCountAfterBuild));
});
testWidgets('MaterialApp.router route information parser is optional', (WidgetTester tester) async {
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
builder: (BuildContext context, RouteInformation information) {