Add navigatorKey to CupertinoTabView (#25183)
This commit is contained in:
parent
8ca8dbf062
commit
65df90d8b5
@ -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);
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user