Flutter路由使用指南
主要有两种方式:基本路由和命名路由。
1. 基本路由
使用 Navigator.push 和 Navigator.pop
import 'package:flutter/material.dart';// 首页
class HomePage extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('首页')),body: Center(child: ElevatedButton(onPressed: () {// 导航到第二个页面Navigator.push(context,MaterialPageRoute(builder: (context) => SecondPage()),);},child: Text('去第二个页面'),),),);}
}// 第二个页面
class SecondPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('第二个页面')),body: Center(child: ElevatedButton(onPressed: () {// 返回上一个页面Navigator.pop(context);},child: Text('返回'),),),);}
}
带参数的路由
// 详情页面,接收参数
class DetailPage extends StatelessWidget {final String itemId;final String itemName;DetailPage({required this.itemId, required this.itemName});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('详情页面')),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children: [Text('ID: $itemId'),Text('名称: $itemName'),ElevatedButton(onPressed: () => Navigator.pop(context),child: Text('返回'),),],),),);}
}// 使用方式
Navigator.push(context,MaterialPageRoute(builder: (context) => DetailPage(itemId: '123',itemName: '示例商品',),),
);
2. 命名路由
配置路由表
void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: '命名路由示例',// 定义路由表routes: {'/': (context) => HomePage(),'/second': (context) => SecondPage(),'/detail': (context) => DetailPage(), // 注意:这种方式不能传递参数},// 或者使用 onGenerateRoute 来处理带参数的路由onGenerateRoute: (settings) {if (settings.name == '/detail') {final args = settings.arguments as Map<String, String>;return MaterialPageRoute(builder: (context) => DetailPage(itemId: args['id']!,itemName: args['name']!,),);}return null;},);}
}
使用命名路由导航
// 简单的命名路由
Navigator.pushNamed(context, '/second');// 带参数的命名路由
Navigator.pushNamed(context,'/detail',arguments: {'id': '123','name': '示例商品',},
);
3. 路由返回值
从页面返回数据
class SelectionPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('选择页面')),body: Center(child: Column(children: [ElevatedButton(onPressed: () {// 返回数据Navigator.pop(context, '选项A');},child: Text('选择A'),),ElevatedButton(onPressed: () {Navigator.pop(context, '选项B');},child: Text('选择B'),),],),),);}
}// 在主页面接收返回值
void _navigateToSelection(BuildContext context) async {final result = await Navigator.push(context,MaterialPageRoute(builder: (context) => SelectionPage()),);// 处理返回结果if (result != null) {print('用户选择了: $result');}
}
4. 路由守卫
使用 onGenerateRoute 进行权限控制
class MyApp extends StatelessWidget {final bool isLoggedIn = false; // 模拟登录状态@overrideWidget build(BuildContext context) {return MaterialApp(onGenerateRoute: (settings) {// 路由守卫 - 检查登录状态if (settings.name == '/profile' && !isLoggedIn) {// 未登录时重定向到登录页面return MaterialPageRoute(builder: (context) => LoginPage(),);}// 正常路由处理switch (settings.name) {case '/':return MaterialPageRoute(builder: (context) => HomePage());case '/profile':return MaterialPageRoute(builder: (context) => ProfilePage());case '/login':return MaterialPageRoute(builder: (context) => LoginPage());default:return MaterialPageRoute(builder: (context) => NotFoundPage(),);}},);}
}
总结
-
基本路由:适合简单的导航场景
-
命名路由:适合复杂的应用结构,便于管理
-
参数传递:可以通过构造函数或路由参数传递
-
返回值:使用
await等待页面返回结果 -
路由守卫:通过
onGenerateRoute实现权限控制
