在 Flutter中,页面跳转通过 Navigator
管理路由栈实现:
// 1. 基本跳转
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
// 2. 带返回结果的跳转
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => SelectionPage()),
);
// 3. 返回上一页
Navigator.pop(context);
// 或带返回值返回
Navigator.pop(context, '返回的数据');
命名路由:通过字符串标识符管理路由,提高可维护性。
定义步骤:
MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => HomePage(),
'/details': (context) => DetailPage(),
'/settings': (context) => SettingsPage(),
},
);
Navigator.pushNamed(context, '/details');
Navigator.pushNamed(
context,
'/details',
arguments: {'id': 100, 'name': 'Flutter'}, // 参数传递
);
// 目标页面
class DetailPage extends StatelessWidget {
final int id;
final String name;
DetailPage({required this.id, required this.name});
// ...
}
// 跳转时传递
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailPage(id: 100, name: 'Flutter'),
),
);
// 目标页面获取参数
class DetailPage extends StatelessWidget {
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as Map;
final id = args['id'];
final name = args['name'];
// ...
}
}
// 跳转时传递参数
Navigator.pushNamed(
context,
'/details',
arguments: {'id': 100, 'name': 'Flutter'},
);
步骤:
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => SelectionPage()),
);
print('收到结果: $result'); // 处理返回结果
// 在 SelectionPage 中
ElevatedButton(
onPressed: () {
Navigator.pop(context, '用户选择了A'); // 返回结果
},
child: Text('选项A'),
)
路由守卫:在路由跳转前后执行拦截逻辑(如权限验证、日志记录)。
实现方式:
使用 MaterialApp
的 onGenerateRoute
和 onGenerateInitialRoutes
:
MaterialApp(
onGenerateRoute: (settings) {
// 路由守卫逻辑
if (_needLogin(settings.name) && !isLoggedIn) {
return MaterialPageRoute( // 拦截并重定向
builder: (context) => LoginPage(),
);
}
// 正常路由处理
switch (settings.name) {
case '/details':
return MaterialPageRoute(
builder: (context) => DetailPage(),
settings: settings, // 传递原始参数
);
// ...其他路由
}
},
);
常见守卫场景:
onGenerateRoute: (settings) {
// 1. 权限验证
if (settings.name == '/admin' && !isAdmin) {
return MaterialPageRoute(builder: (_) => AccessDeniedPage());
}
// 2. 数据预加载
if (settings.name == '/profile') {
final userId = settings.arguments as String;
precacheUserData(userId); // 预加载数据
}
// 3. 路由日志
logRouteChange(settings.name);
// ...正常路由处理
}
完整示例:
MaterialApp(
onGenerateRoute: (settings) {
// 身份验证守卫
final requireAuth = ['/profile', '/settings'].contains(settings.name);
if (requireAuth && !isAuthenticated) {
return MaterialPageRoute(
builder: (_) => LoginPage(),
settings: RouteSettings(name: '/login'), // 重设路由名
);
}
// 参数验证守卫
if (settings.name == '/product' && settings.arguments == null) {
return MaterialPageRoute(builder: (_) => NotFoundPage());
}
// 路由匹配
switch (settings.name) {
case '/product':
final productId = settings.arguments as String;
return MaterialPageRoute(
builder: (_) => ProductPage(id: productId),
);
default:
return MaterialPageRoute(builder: (_) => HomePage());
}
},
);