enable Navigator.of to accept a navigator element and return its stat… (#58259)

This commit is contained in:
chunhtai 2020-06-08 16:13:02 -07:00 committed by GitHub
parent 023532d991
commit 333eb9d76a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 3 deletions

View file

@ -2132,9 +2132,17 @@ class Navigator extends StatefulWidget {
bool rootNavigator = false,
bool nullOk = false,
}) {
final NavigatorState navigator = rootNavigator
? context.findRootAncestorStateOfType<NavigatorState>()
: context.findAncestorStateOfType<NavigatorState>();
// Handles the case where the input context is a navigator element.
NavigatorState navigator;
if (context is StatefulElement && context.state is NavigatorState) {
navigator = context.state as NavigatorState;
}
if (rootNavigator) {
navigator = context.findRootAncestorStateOfType<NavigatorState>() ?? navigator;
} else {
navigator = navigator ?? context.findAncestorStateOfType<NavigatorState>();
}
assert(() {
if (navigator == null && !nullOk) {
throw FlutterError(

View file

@ -257,6 +257,46 @@ void main() {
expect(await result, equals(42));
});
testWidgets('Can show dialog using navigator global key', (WidgetTester tester) async {
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
await tester.pumpWidget(
MaterialApp(
navigatorKey: navigator,
home: const Material(
child: Center(
child: Text('Go'),
),
),
),
);
final Future<int> result = showDialog<int>(
context: navigator.currentContext,
builder: (BuildContext context) {
return SimpleDialog(
title: const Text('Title'),
children: <Widget>[
SimpleDialogOption(
onPressed: () {
Navigator.pop(context, 42);
},
child: const Text('First option'),
),
const SimpleDialogOption(
child: Text('Second option'),
),
],
);
},
);
await tester.pumpAndSettle(const Duration(seconds: 1));
expect(find.text('Title'), findsOneWidget);
await tester.tap(find.text('First option'));
expect(await result, equals(42));
});
testWidgets('Custom padding on SimpleDialogOption', (WidgetTester tester) async {
const EdgeInsets customPadding = EdgeInsets.fromLTRB(4, 10, 8, 6);
final SimpleDialog dialog = SimpleDialog(

View file

@ -1753,6 +1753,41 @@ void main() {
expect(find.text('World'), findsNothing);
});
testWidgets('Navigator.of able to handle input context is a navigator context', (WidgetTester tester) async {
final GlobalKey<NavigatorState> g = GlobalKey<NavigatorState>();
await tester.pumpWidget(
MaterialApp(
navigatorKey: g,
home: const Text('home'),
)
);
final NavigatorState state = Navigator.of(g.currentContext);
expect(state, g.currentState);
});
testWidgets('Navigator.of able to handle input context is a navigator context - root navigator', (WidgetTester tester) async {
final GlobalKey<NavigatorState> root = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> sub = GlobalKey<NavigatorState>();
await tester.pumpWidget(
MaterialApp(
navigatorKey: root,
home: Navigator(
key: sub,
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<void>(
settings: settings,
builder: (BuildContext context) => const Text('dummy'),
);
},
),
)
);
final NavigatorState state = Navigator.of(sub.currentContext, rootNavigator: true);
expect(state, root.currentState);
});
testWidgets('pushAndRemove until animates the push', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/25080.