面试题答案
一键面试实现嵌套导航
- 创建嵌套 Navigator:
- 在 Flutter 中,可以通过在
Widget
树中嵌套Navigator
组件来实现嵌套导航。例如,假设我们有一个主Navigator
,然后在某个页面中需要一个子Navigator
。 - 首先定义主
Navigator
,通常在MaterialApp
或CupertinoApp
中:
- 在 Flutter 中,可以通过在
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MainNavigator(),
);
}
}
class MainNavigator extends StatefulWidget {
@override
State<MainNavigator> createState() => _MainNavigatorState();
}
class _MainNavigatorState extends State<MainNavigator> {
@override
Widget build(BuildContext context) {
return Navigator(
initialRoute: '/',
onGenerateRoute: (settings) {
switch (settings.name) {
case '/':
return MaterialPageRoute(builder: (context) => const HomePage());
case '/page1':
return MaterialPageRoute(builder: (context) => const Page1());
default:
return null;
}
},
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home Page'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/page1');
},
child: const Text('Go to Page 1'),
),
),
);
}
}
class Page1 extends StatelessWidget {
const Page1({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Page 1'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
// 这里可以启动子 Navigator
},
child: const Text('Start Sub - Navigator'),
),
),
);
}
}
- 然后在
Page1
中添加子Navigator
:
class Page1 extends StatelessWidget {
const Page1({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Page 1'),
),
body: Center(
child: Navigator(
initialRoute: '/subHome',
onGenerateRoute: (settings) {
switch (settings.name) {
case '/subHome':
return MaterialPageRoute(builder: (context) => const SubHomePage());
case '/subPage1':
return MaterialPageRoute(builder: (context) => const SubPage1());
default:
return null;
}
},
),
),
);
}
}
class SubHomePage extends StatelessWidget {
const SubHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sub - Home Page'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/subPage1');
},
child: const Text('Go to Sub - Page 1'),
),
),
);
}
}
class SubPage1 extends StatelessWidget {
const SubPage1({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sub - Page 1'),
),
body: const Center(
child: Text('This is Sub - Page 1'),
),
);
}
}
管理和处理不同层级 Navigator 的导航状态
- 在子 Navigator 中影响父 Navigator 的状态:
- 可以通过
GlobalKey<NavigatorState>
来访问不同层级的Navigator
。 - 首先在主
Navigator
中定义一个GlobalKey
:
- 可以通过
class MainNavigator extends StatefulWidget {
static final GlobalKey<NavigatorState> mainNavigatorKey = GlobalKey<NavigatorState>();
@override
State<MainNavigator> createState() => _MainNavigatorState();
}
- 在子
Navigator
中,如果要影响父Navigator
的状态,例如返回上一页:
class SubPage1 extends StatelessWidget {
const SubPage1({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sub - Page 1'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
// 返回父 Navigator 的上一页
MainNavigator.mainNavigatorKey.currentState?.pop();
},
child: const Text('Pop Parent Navigator'),
),
),
);
}
}
- 也可以通过传递回调函数的方式来处理。在父
Widget
中定义回调函数,然后传递给子Widget
,子Widget
调用回调函数来影响父Navigator
的状态。例如,在Page1
中定义一个回调函数并传递给SubPage1
:
class Page1 extends StatelessWidget {
const Page1({super.key});
void _popParentNavigator() {
MainNavigator.mainNavigatorKey.currentState?.pop();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Page 1'),
),
body: Center(
child: Navigator(
initialRoute: '/subHome',
onGenerateRoute: (settings) {
switch (settings.name) {
case '/subHome':
return MaterialPageRoute(builder: (context) => const SubHomePage());
case '/subPage1':
return MaterialPageRoute(builder: (context) => SubPage1(popParent: _popParentNavigator));
default:
return null;
}
},
),
),
);
}
}
class SubPage1 extends StatelessWidget {
final VoidCallback popParent;
const SubPage1({super.key, required this.popParent});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sub - Page 1'),
),
body: Center(
child: ElevatedButton(
onPressed: popParent,
child: const Text('Pop Parent Navigator'),
),
),
);
}
}
通过上述方法,可以在 Flutter 中正确实现嵌套导航,并有效地管理和处理不同层级 Navigator 的导航状态。