Skip to content

Commit ade8af2

Browse files
authored
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 flutter/flutter#120385. This PR passes them through. Fixes flutter/flutter#139903 @maRci0002 Would this totally fix your issue flutter/flutter#139903?
1 parent 1af09dd commit ade8af2

File tree

5 files changed

+100
-1
lines changed

5 files changed

+100
-1
lines changed

packages/flutter/lib/src/cupertino/app.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ class _CupertinoAppState extends State<CupertinoApp> {
547547
routerDelegate: widget.routerDelegate,
548548
routerConfig: widget.routerConfig,
549549
backButtonDispatcher: widget.backButtonDispatcher,
550+
onNavigationNotification: widget.onNavigationNotification,
550551
builder: widget.builder,
551552
title: widget.title,
552553
onGenerateTitle: widget.onGenerateTitle,

packages/flutter/lib/src/material/app.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,7 @@ class _MaterialAppState extends State<MaterialApp> {
10161016
routerDelegate: widget.routerDelegate,
10171017
routerConfig: widget.routerConfig,
10181018
backButtonDispatcher: widget.backButtonDispatcher,
1019+
onNavigationNotification: widget.onNavigationNotification,
10191020
builder: _materialBuilder,
10201021
title: widget.title,
10211022
onGenerateTitle: widget.onGenerateTitle,

packages/flutter/lib/src/widgets/app.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,12 @@ class WidgetsApp extends StatefulWidget {
706706
/// {@template flutter.widgets.widgetsApp.onNavigationNotification}
707707
/// The callback to use when receiving a [NavigationNotification].
708708
///
709-
/// By default this updates the engine with the navigation status.
709+
/// By default this updates the engine with the navigation status and stops
710+
/// bubbling the notification.
711+
///
712+
/// See also:
713+
///
714+
/// * [NotificationListener.onNotification], which uses this callback.
710715
/// {@endtemplate}
711716
final NotificationListenerCallback<NavigationNotification>? onNavigationNotification;
712717

packages/flutter/test/cupertino/app_test.dart

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,52 @@ void main() {
179179
expect(find.text('popped'), findsOneWidget);
180180
});
181181

182+
testWidgets('CupertinoApp.router works with onNavigationNotification', (WidgetTester tester) async {
183+
// This is a regression test for https://github.com/flutter/flutter/issues/139903.
184+
final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider(
185+
initialRouteInformation: RouteInformation(
186+
uri: Uri.parse('initial'),
187+
),
188+
);
189+
addTearDown(provider.dispose);
190+
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
191+
builder: (BuildContext context, RouteInformation information) {
192+
return Text(information.uri.toString());
193+
},
194+
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
195+
delegate.routeInformation = RouteInformation(
196+
uri: Uri.parse('popped'),
197+
);
198+
return route.didPop(result);
199+
},
200+
);
201+
addTearDown(delegate.dispose);
202+
203+
int navigationCount = 0;
204+
205+
await tester.pumpWidget(CupertinoApp.router(
206+
routeInformationProvider: provider,
207+
routeInformationParser: SimpleRouteInformationParser(),
208+
routerDelegate: delegate,
209+
onNavigationNotification: (NavigationNotification? notification) {
210+
navigationCount += 1;
211+
return true;
212+
},
213+
));
214+
expect(find.text('initial'), findsOneWidget);
215+
216+
expect(navigationCount, greaterThan(0));
217+
final int navigationCountAfterBuild = navigationCount;
218+
219+
// Simulate android back button intent.
220+
final ByteData message = const JSONMethodCodec().encodeMethodCall(const MethodCall('popRoute'));
221+
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
222+
await tester.pumpAndSettle();
223+
expect(find.text('popped'), findsOneWidget);
224+
225+
expect(navigationCount, greaterThan(navigationCountAfterBuild));
226+
});
227+
182228
testWidgets('CupertinoApp.router route information parser is optional', (WidgetTester tester) async {
183229
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
184230
builder: (BuildContext context, RouteInformation information) {

packages/flutter/test/material/app_test.dart

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,52 @@ void main() {
11181118
expect(find.text('popped'), findsOneWidget);
11191119
});
11201120

1121+
testWidgets('MaterialApp.router works with onNavigationNotification', (WidgetTester tester) async {
1122+
// This is a regression test for https://github.com/flutter/flutter/issues/139903.
1123+
final PlatformRouteInformationProvider provider = PlatformRouteInformationProvider(
1124+
initialRouteInformation: RouteInformation(
1125+
uri: Uri.parse('initial'),
1126+
),
1127+
);
1128+
addTearDown(provider.dispose);
1129+
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
1130+
builder: (BuildContext context, RouteInformation information) {
1131+
return Text(information.uri.toString());
1132+
},
1133+
onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
1134+
delegate.routeInformation = RouteInformation(
1135+
uri: Uri.parse('popped'),
1136+
);
1137+
return route.didPop(result);
1138+
},
1139+
);
1140+
addTearDown(delegate.dispose);
1141+
1142+
int navigationCount = 0;
1143+
1144+
await tester.pumpWidget(MaterialApp.router(
1145+
routeInformationProvider: provider,
1146+
routeInformationParser: SimpleRouteInformationParser(),
1147+
routerDelegate: delegate,
1148+
onNavigationNotification: (NavigationNotification? notification) {
1149+
navigationCount += 1;
1150+
return true;
1151+
},
1152+
));
1153+
expect(find.text('initial'), findsOneWidget);
1154+
1155+
expect(navigationCount, greaterThan(0));
1156+
final int navigationCountAfterBuild = navigationCount;
1157+
1158+
// Simulate android back button intent.
1159+
final ByteData message = const JSONMethodCodec().encodeMethodCall(const MethodCall('popRoute'));
1160+
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
1161+
await tester.pumpAndSettle();
1162+
expect(find.text('popped'), findsOneWidget);
1163+
1164+
expect(navigationCount, greaterThan(navigationCountAfterBuild));
1165+
});
1166+
11211167
testWidgets('MaterialApp.router route information parser is optional', (WidgetTester tester) async {
11221168
final SimpleNavigatorRouterDelegate delegate = SimpleNavigatorRouterDelegate(
11231169
builder: (BuildContext context, RouteInformation information) {

0 commit comments

Comments
 (0)