当前位置: 首页 > news >正文

Flutter路由导航详解:从基础到高级

Flutter路由导航详解从基础到高级一、Flutter导航基础在Flutter中导航管理着应用的页面栈。每个页面都是一个Route通过Navigator进行管理。1.1 Navigator的基本概念Navigator是一个管理路由栈的Widget提供了push和pop操作来管理页面导航。// 基本导航操作 Navigator.push(context, MaterialPageRoute(builder: (context) const SecondPage())); Navigator.pop(context);1.2 MaterialPageRouteMaterialPageRoute是最常用的路由类提供了Material风格的页面过渡动画。MaterialPageRoute( builder: (context) const SecondPage(), settings: const RouteSettings( name: /second, arguments: {id: 123}, ), )二、基础导航操作2.1 导航到新页面ElevatedButton( onPressed: () { Navigator.push( context, MaterialPageRoute( builder: (context) const DetailPage(), ), ); }, child: const Text(Go to Detail), )2.2 返回上一页ElevatedButton( onPressed: () { Navigator.pop(context); }, child: const Text(Go Back), )2.3 返回并传递数据// 在子页面中返回数据 ElevatedButton( onPressed: () { Navigator.pop(context, {result: success}); }, child: const Text(Return with Data), ) // 在父页面中接收返回数据 final result await Navigator.push( context, MaterialPageRoute(builder: (context) const SecondPage()), ); if (result ! null) { print(Result: ${result[result]}); }三、命名路由3.1 注册命名路由MaterialApp( initialRoute: /, routes: { /: (context) const HomePage(), /second: (context) const SecondPage(), /detail: (context) const DetailPage(), }, )3.2 使用命名路由导航Navigator.pushNamed(context, /second); Navigator.pushNamed(context, /detail);3.3 传递参数Navigator.pushNamed( context, /detail, arguments: {id: 123, name: Flutter}, );3.4 获取参数class DetailPage extends StatelessWidget { const DetailPage({super.key}); override Widget build(BuildContext context) { final args ModalRoute.of(context)?.settings.arguments as Map; final id args[id] as int; final name args[name] as String; return Scaffold( appBar: AppBar(title: const Text(Detail)), body: Center( child: Text(ID: $id, Name: $name), ), ); } }四、GoRouter高级路由GoRouter是Flutter官方推荐的路由管理方案提供了声明式路由、嵌套路由等高级功能。4.1 添加依赖dependencies: go_router: ^12.0.04.2 基本配置final GoRouter _router GoRouter( routes: RouteBase[ GoRoute( path: /, builder: (BuildContext context, GoRouterState state) { return const HomePage(); }, ), GoRoute( path: /second, builder: (BuildContext context, GoRouterState state) { return const SecondPage(); }, ), ], ); class MyApp extends StatelessWidget { const MyApp({super.key}); override Widget build(BuildContext context) { return MaterialApp.router( routerConfig: _router, title: Flutter Demo, ); } }4.3 带参数的路由GoRoute( path: /detail/:id, builder: (BuildContext context, GoRouterState state) { final id state.params[id]!; return DetailPage(id: id); }, )4.4 查询参数GoRoute( path: /search, builder: (BuildContext context, GoRouterState state) { final query state.uri.queryParameters[q] ?? ; return SearchPage(query: query); }, ) // 使用 context.push(/search?qflutter);4.5 嵌套路由GoRoute( path: /dashboard, builder: (context, state) const DashboardPage(), routes: [ GoRoute( path: profile, builder: (context, state) const ProfilePage(), ), GoRoute( path: settings, builder: (context, state) const SettingsPage(), ), ], )4.6 Shell路由共享UIfinal GoRouter _router GoRouter( routes: [ ShellRoute( builder: (context, state, child) { return Scaffold( body: child, bottomNavigationBar: BottomNavigationBar( items: const [ BottomNavigationBarItem(icon: Icon(Icons.home), label: Home), BottomNavigationBarItem(icon: Icon(Icons.settings), label: Settings), ], ), ); }, routes: [ GoRoute( path: /, builder: (context, state) const HomePage(), ), GoRoute( path: /settings, builder: (context, state) const SettingsPage(), ), ], ), ], );五、路由守卫5.1 全局守卫final GoRouter _router GoRouter( redirect: (BuildContext context, GoRouterState state) { final isLoggedIn AuthService.instance.isLoggedIn; final isLoginRoute state.matchedLocation /login; if (!isLoggedIn !isLoginRoute) { return /login; } if (isLoggedIn isLoginRoute) { return /; } return null; }, routes: [...], );5.2 路由级别守卫GoRoute( path: /profile, builder: (context, state) const ProfilePage(), redirect: (context, state) { if (!AuthService.instance.isLoggedIn) { return /login; } return null; }, )六、页面过渡动画6.1 自定义页面过渡PageRouteBuilder( pageBuilder: (context, animation, secondaryAnimation) const SecondPage(), transitionsBuilder: (context, animation, secondaryAnimation, child) { const begin Offset(1.0, 0.0); const end Offset.zero; const curve Curves.ease; var tween Tween(begin: begin, end: end).chain(CurveTween(curve: curve)); return SlideTransition( position: animation.drive(tween), child: child, ); }, )6.2 淡入淡出效果PageRouteBuilder( pageBuilder: (context, animation, secondaryAnimation) const SecondPage(), transitionsBuilder: (context, animation, secondaryAnimation, child) { return FadeTransition( opacity: animation, child: child, ); }, )6.3 缩放效果PageRouteBuilder( pageBuilder: (context, animation, secondaryAnimation) const SecondPage(), transitionsBuilder: (context, animation, secondaryAnimation, child) { return ScaleTransition( scale: animation.drive( Tweendouble(begin: 0.5, end: 1.0).chain(CurveTween(curve: Curves.easeOut)), ), child: child, ); }, )七、Hero动画Hero动画允许在页面之间共享Widget的平滑过渡。7.1 基本用法// 源页面 Hero( tag: imageHero, child: Image.network(https://example.com/image.jpg), ) // 目标页面 Hero( tag: imageHero, child: Image.network(https://example.com/image.jpg), )7.2 自定义Hero动画Hero( tag: customHero, createRectTween: (begin, end) { return MaterialRectCenterArcTween(begin: begin, end: end); }, child: const Icon(Icons.star), )八、BottomNavigationBar导航class HomePage extends StatefulWidget { const HomePage({super.key}); override StateHomePage createState() _HomePageState(); } class _HomePageState extends StateHomePage { int _selectedIndex 0; static const ListWidget _widgetOptions [ HomeContent(), SearchContent(), ProfileContent(), ]; void _onItemTapped(int index) { setState(() { _selectedIndex index; }); } override Widget build(BuildContext context) { return Scaffold( body: _widgetOptions.elementAt(_selectedIndex), bottomNavigationBar: BottomNavigationBar( items: const [ BottomNavigationBarItem( icon: Icon(Icons.home), label: Home, ), BottomNavigationBarItem( icon: Icon(Icons.search), label: Search, ), BottomNavigationBarItem( icon: Icon(Icons.person), label: Profile, ), ], currentIndex: _selectedIndex, selectedItemColor: Colors.blue, onTap: _onItemTapped, ), ); } }九、TabBar导航class TabNavigation extends StatefulWidget { const TabNavigation({super.key}); override StateTabNavigation createState() _TabNavigationState(); } class _TabNavigationState extends StateTabNavigation with SingleTickerProviderStateMixin { late TabController _tabController; override void initState() { super.initState(); _tabController TabController(length: 3, vsync: this); } override void dispose() { _tabController.dispose(); super.dispose(); } override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( bottom: TabBar( controller: _tabController, tabs: const [ Tab(icon: Icon(Icons.home), text: Home), Tab(icon: Icon(Icons.search), text: Search), Tab(icon: Icon(Icons.person), text: Profile), ], ), ), body: TabBarView( controller: _tabController, children: const [ HomeContent(), SearchContent(), ProfileContent(), ], ), ); } }十、Deep Linking深度链接10.1 配置Deep Link在pubspec.yaml中添加依赖dependencies: flutter_deep_linking: ^0.2.010.2 处理Deep Linkfinal GoRouter _router GoRouter( routes: [ GoRoute( path: /product/:id, builder: (context, state) { final id state.params[id]!; return ProductDetailPage(id: id); }, ), ], );10.3 Android配置在AndroidManifest.xml中添加intent-filter action android:nameandroid.intent.action.VIEW / category android:nameandroid.intent.category.DEFAULT / category android:nameandroid.intent.category.BROWSABLE / data android:schememyapp android:hostexample.com / /intent-filter10.4 iOS配置在Info.plist中添加keyCFBundleURLTypes/key array dict keyCFBundleURLSchemes/key array stringmyapp/string /array keyCFBundleURLName/key stringcom.example.myapp/string /dict /array十一、路由管理最佳实践11.1 使用GoRouter进行集中管理final GoRouter router GoRouter( initialLocation: /, routes: [ GoRoute( path: /, name: home, builder: (context, state) const HomePage(), ), GoRoute( path: /login, name: login, builder: (context, state) const LoginPage(), ), GoRoute( path: /dashboard, name: dashboard, builder: (context, state) const DashboardPage(), routes: [ GoRoute( path: profile, name: profile, builder: (context, state) const ProfilePage(), ), ], ), ], );11.2 使用enum定义路由名称enum AppRoute { home(/), login(/login), dashboard(/dashboard), profile(/dashboard/profile); final String path; const AppRoute(this.path); } // 使用 context.push(AppRoute.profile.path);11.3 错误路由处理final GoRouter _router GoRouter( errorBuilder: (context, state) const NotFoundPage(), routes: [...], );总结Flutter提供了丰富的导航方案从基础的Navigator到高级的GoRouter。关键要点基础导航使用Navigator.push和Navigator.pop进行简单导航命名路由通过routes配置实现声明式路由管理GoRouter官方推荐的路由管理方案支持嵌套路由和路由守卫页面过渡支持自定义动画效果Hero动画实现页面间共享元素的平滑过渡Tab导航使用TabBar和BottomNavigationBar实现底部/顶部导航Deep Linking支持从外部链接跳转到应用内指定页面选择合适的导航方案取决于项目的复杂度和需求。对于简单应用基础Navigator足够对于复杂应用推荐使用GoRouter进行集中管理。
http://www.zskr.cn/news/1371822.html

相关文章:

  • 如何快速配置科学机器学习环境:DeepXDE完整安装指南
  • 如何快速上手DouZero斗地主AI助手:面向新手的完整实战指南
  • 国内知名的透明化三维重构品牌名声
  • 【算法分析与设计】第1篇:算法分析与设计的学科范畴与方法论
  • 2026 连云港黄金回收市场调研|本地管家回收对标本土品牌 全网搜索需求深度剖析 - 鑫顺黄金回收
  • 2026年5月常德汉寿地区黄金回收白银铂金回收门店推荐TOP1 地址及联系方式 - 检测回收中心
  • 2025-2026年DHA品牌推荐:十大排行评测夜读提神性价比高注意事项
  • AI Agent Harness Engineering 的能耗问题:绿色 AI 与推理成本的平衡艺术
  • 不关Secure Boot!用mokutil永久解决Linux内核模块签名问题(附自动化脚本)
  • 整合OpenClaw与Taotoken,构建高效自动化AI智能体工作流
  • 鼎讯Smart-E3:为交通大动脉的通信“血管”提供专业测试方案
  • 学校运动会信息管理系统(10086)
  • 云原生可观测性体系建设:从0到1搭Prometheus+Grafana+ELK+SkyWalking全家桶
  • 为什么大模型分词器不用保存词表?揭秘 Karpathy 的“零冗余”持久化设计
  • Agent 一接侧边详情面板就开始改错对象:从 Panel Claim 到 Entity Proof 的工程实战
  • 2026年5月海南省琼中地区黄金回收白银铂金回收门店推荐TOP1 地址及联系方式 - 诚信金利回收
  • 实战指南:使用Dock构建现代化Avalonia应用布局系统
  • Loop:终极免费开源Mac窗口管理工具,彻底解决桌面杂乱问题
  • League Akari:重新定义英雄联盟玩家的智能游戏体验
  • 5分钟掌握SRWE:Windows窗口分辨率自由调整的终极指南
  • [特殊字符] Lucky从零到一的系统搭建里程碑 | 写给后人的初心与使命
  • 2026中国GEO企业成长路径分析洞察
  • 2026年5月北京朝阳地区黄金回收白银铂金回收门店推荐TOP1 地址及联系方式 - 检测回收中心
  • 智能体通信的序列化标准探索:JSON、ProtoBuf与自定义格式的效率之争
  • 在Node.js后端服务中接入Taotoken实现异步AI对话功能
  • 3分钟掌握图像矢量化神器:从像素马赛克到无限缩放矢量图
  • 在Ubuntu 22.04上,用AutoDockTools给蛋白加氢和准备配体,保姆级避坑指南
  • 别再乱格分区了!Win11+Ubuntu双系统和平共处的正确卸载与引导修复指南
  • 79万中文医疗对话数据集:打造智能医疗问答系统的终极语料库指南
  • Gemini CSR不是公关秀——而是技术向善的底层操作系统:基于17家头部客户落地数据的6维价值转化模型