Unverified Commit 65df90d8 authored by xster's avatar xster Committed by GitHub

Add navigatorKey to CupertinoTabView (#25183)

parent 8ca8dbf0
......@@ -43,6 +43,7 @@ class CupertinoTabView extends StatefulWidget {
const CupertinoTabView({
Key key,
this.builder,
this.navigatorKey,
this.defaultTitle,
this.routes,
this.onGenerateRoute,
......@@ -58,6 +59,19 @@ class CupertinoTabView extends StatefulWidget {
/// as [builder] takes its place.
final WidgetBuilder builder;
/// A key to use when building this widget's [Navigator].
///
/// If a [navigatorKey] is specified, the [Navigator] can be directly
/// manipulated without first obtaining it from a [BuildContext] via
/// [Navigator.of]: from the [navigatorKey], use the [GlobalKey.currentState]
/// getter.
///
/// If this is changed, a new [Navigator] will be created, losing all the
/// tab's state in the process; in that case, the [navigatorObservers]
/// must also be changed, since the previous observers will be attached to the
/// previous navigator.
final GlobalKey<NavigatorState> navigatorKey;
/// The title of the default route.
final String defaultTitle;
......@@ -120,9 +134,12 @@ class _CupertinoTabViewState extends State<CupertinoTabView> {
}
@override
void didUpdateWidget(CupertinoTabView oldWidget) {
super.didUpdateWidget(oldWidget);
_updateObservers();
void didUpdateWidget(CupertinoTabView oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.navigatorKey != oldWidget.navigatorKey
|| widget.navigatorObservers != oldWidget.navigatorObservers) {
_updateObservers();
}
}
void _updateObservers() {
......@@ -134,6 +151,7 @@ class _CupertinoTabViewState extends State<CupertinoTabView> {
@override
Widget build(BuildContext context) {
return Navigator(
key: widget.navigatorKey,
onGenerateRoute: _onGenerateRoute,
onUnknownRoute: _onUnknownRoute,
observers: _navigatorObservers,
......
......@@ -96,4 +96,75 @@ void main() {
expect(tester.takeException(), isFlutterError);
expect(unknownForRouteCalled, '/');
});
testWidgets('Can use navigatorKey to navigate', (WidgetTester tester) async {
final GlobalKey<NavigatorState> key = GlobalKey();
await tester.pumpWidget(
CupertinoApp(
home: CupertinoTabView(
navigatorKey: key,
builder: (BuildContext context) => const Text('first route'),
routes: <String, WidgetBuilder>{
'/2': (BuildContext context) => const Text('second route'),
},
),
),
);
key.currentState.pushNamed('/2');
await tester.pump();
await tester.pump(const Duration(milliseconds: 300));
expect(find.text('second route'), findsOneWidget);
});
testWidgets('Changing the key resets the navigator', (WidgetTester tester) async {
final GlobalKey<NavigatorState> key = GlobalKey();
await tester.pumpWidget(
CupertinoApp(
home: CupertinoTabView(
builder: (BuildContext context) {
return CupertinoButton(
child: const Text('go to second page'),
onPressed: () {
Navigator.of(context).pushNamed('/2');
},
);
},
routes: <String, WidgetBuilder>{
'/2': (BuildContext context) => const Text('second route'),
},
),
),
);
expect(find.text('go to second page'), findsOneWidget);
await tester.tap(find.text('go to second page'));
await tester.pump();
await tester.pump(const Duration(milliseconds: 300));
expect(find.text('second route'), findsOneWidget);
await tester.pumpWidget(
CupertinoApp(
home: CupertinoTabView(
key: key,
builder: (BuildContext context) {
return CupertinoButton(
child: const Text('go to second page'),
onPressed: () {
Navigator.of(context).pushNamed('/2');
},
);
},
routes: <String, WidgetBuilder>{
'/2': (BuildContext context) => const Text('second route'),
},
),
),
);
// The stack is gone and we're back to a re-built page 1.
expect(find.text('go to second page'), findsOneWidget);
expect(find.text('second route'), findsNothing);
});
}
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