Add navigatorKey to CupertinoTabView (#25183)
This commit is contained in:
parent
8ca8dbf062
commit
65df90d8b5
@ -43,6 +43,7 @@ class CupertinoTabView extends StatefulWidget {
|
|||||||
const CupertinoTabView({
|
const CupertinoTabView({
|
||||||
Key key,
|
Key key,
|
||||||
this.builder,
|
this.builder,
|
||||||
|
this.navigatorKey,
|
||||||
this.defaultTitle,
|
this.defaultTitle,
|
||||||
this.routes,
|
this.routes,
|
||||||
this.onGenerateRoute,
|
this.onGenerateRoute,
|
||||||
@ -58,6 +59,19 @@ class CupertinoTabView extends StatefulWidget {
|
|||||||
/// as [builder] takes its place.
|
/// as [builder] takes its place.
|
||||||
final WidgetBuilder builder;
|
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.
|
/// The title of the default route.
|
||||||
final String defaultTitle;
|
final String defaultTitle;
|
||||||
|
|
||||||
@ -122,8 +136,11 @@ class _CupertinoTabViewState extends State<CupertinoTabView> {
|
|||||||
@override
|
@override
|
||||||
void didUpdateWidget(CupertinoTabView oldWidget) {
|
void didUpdateWidget(CupertinoTabView oldWidget) {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
|
if (widget.navigatorKey != oldWidget.navigatorKey
|
||||||
|
|| widget.navigatorObservers != oldWidget.navigatorObservers) {
|
||||||
_updateObservers();
|
_updateObservers();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _updateObservers() {
|
void _updateObservers() {
|
||||||
_navigatorObservers =
|
_navigatorObservers =
|
||||||
@ -134,6 +151,7 @@ class _CupertinoTabViewState extends State<CupertinoTabView> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Navigator(
|
return Navigator(
|
||||||
|
key: widget.navigatorKey,
|
||||||
onGenerateRoute: _onGenerateRoute,
|
onGenerateRoute: _onGenerateRoute,
|
||||||
onUnknownRoute: _onUnknownRoute,
|
onUnknownRoute: _onUnknownRoute,
|
||||||
observers: _navigatorObservers,
|
observers: _navigatorObservers,
|
||||||
|
@ -96,4 +96,75 @@ void main() {
|
|||||||
expect(tester.takeException(), isFlutterError);
|
expect(tester.takeException(), isFlutterError);
|
||||||
expect(unknownForRouteCalled, '/');
|
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