4.1 Navigator 与 Route

张开发
2026/6/1 9:53:46 15 分钟阅读
4.1 Navigator 与 Route
Flutter 的导航系统分为 Navigator 1.0命令式和 Navigator 2.0声明式两代。理解两者的差异有助于选择合适的导航方案。一、Navigator 1.0命令式导航Navigator 1.0 是传统的命令式导航通过 push/pop 操作路由栈。1.1 基本导航操作// push压栈进入新页面Navigator.push(context,MaterialPageRoute(builder:(_)constDetailPage()),);// pop出栈返回上一页Navigator.pop(context);// pop 并传递返回值Navigator.pop(context,result_data);// 接收返回值finalresultawaitNavigator.pushString(context,MaterialPageRoute(builder:(_)constEditPage()),);print(Returned:$result);// pushReplacement替换当前页面不可返回Navigator.pushReplacement(context,MaterialPageRoute(builder:(_)constHomePage()),);// pushAndRemoveUntil清空路由栈跳转Navigator.pushAndRemoveUntil(context,MaterialPageRoute(builder:(_)constLoginPage()),(route)false,// false 清空所有);// popUntil返回到指定路由Navigator.popUntil(context,ModalRoute.withName(/home));1.2 命名路由pushNamed// 注册路由表MaterialApp(initialRoute:/,routes:{/:(context)constHomePage(),/product:(context)constProductPage(),/login:(context)constLoginPage(),/profile:(context)constProfilePage(),},)// 使用命名路由导航Navigator.pushNamed(context,/product);// 传递参数Navigator.pushNamed(context,/product,arguments:{productId:123,from:home},);// 在目标页面接收参数classProductPageextendsStatelessWidget{overrideWidgetbuild(BuildContextcontext){finalargsModalRoute.of(context)!.settings.argumentsasMapString,dynamic;finalproductIdargs[productId]asint;returnText(Product$productId);}}1.3 onGenerateRoute动态路由生成MaterialApp(onGenerateRoute:(settings){// 解析路由路径支持动态参数finaluriUri.parse(settings.name??/);switch(uri.pathSegments.first){caseproduct:finalidint.tryParse(uri.pathSegments.last);returnMaterialPageRoute(builder:(_)ProductDetailPage(productId:id!),settings:settings,);casecategory:finalsluguri.pathSegments.last;returnMaterialPageRoute(builder:(_)CategoryPage(slug:slug),);default:returnMaterialPageRoute(builder:(_)constNotFoundPage());}},onUnknownRoute:(settings)MaterialPageRoute(builder:(_)constNotFoundPage(),),)二、Navigator 2.0声明式导航Navigator 2.0 将路由变成了状态通过声明式方式描述路由栈更适合 Web 端的 URL 管理和深链。2.1 RouterDelegateclassAppRouterDelegateextendsRouterDelegateAppRoutePathwithChangeNotifier,PopNavigatorRouterDelegateMixinAppRoutePath{overridefinalGlobalKeyNavigatorStatenavigatorKeyGlobalKeyNavigatorState();AppRoutePath_currentPathAppRoutePath.home();// 当前路由状态AppRoutePathgetcurrentPath_currentPath;voidnavigateTo(AppRoutePathpath){_currentPathpath;notifyListeners();// 通知导航系统重建路由栈}overrideAppRoutePathgetcurrentConfiguration_currentPath;overrideWidgetbuild(BuildContextcontext){// 声明式根据状态描述路由栈returnNavigator(key:navigatorKey,pages:[constMaterialPage(key:ValueKey(home),child:HomePage()),if(_currentPath.isProduct)MaterialPage(key:ValueKey(product_${_currentPath.productId}),child:ProductDetailPage(productId:_currentPath.productId!),),],onPopPage:(route,result){if(!route.didPop(result))returnfalse;navigateTo(AppRoutePath.home());returntrue;},);}overrideFuturevoidsetNewRoutePath(AppRoutePathpath)async{_currentPathpath;}}2.2 RouteInformationParserclassAppRouteInformationParserextendsRouteInformationParserAppRoutePath{overrideFutureAppRoutePathparseRouteInformation(RouteInformationinfo)async{finaluriUri.parse(info.location??/);if(uri.pathSegments.isEmpty)returnAppRoutePath.home();if(uri.pathSegments.firstproducturi.pathSegments.length2){returnAppRoutePath.product(int.parse(uri.pathSegments[1]));}returnAppRoutePath.unknown();}overrideRouteInformation?restoreRouteInformation(AppRoutePathpath){if(path.isHome)returnconstRouteInformation(location:/);if(path.isProduct)returnRouteInformation(location:/product/${path.productId});returnconstRouteInformation(location:/404);}}三、MaterialPageRoute 与自定义 Route3.1 MaterialPageRoute// 标准 Material 风格过渡Android底部滑入iOS右侧滑入Navigator.push(context,MaterialPageRoute(builder:(_)constDetailPage(),fullscreenDialog:true,// iOS 全屏模态样式从底部滑入maintainState:false,// 返回时是否保留状态),)3.2 CupertinoPageRoute// iOS 风格过渡右侧滑入支持边缘滑动返回Navigator.push(context,CupertinoPageRoute(builder:(_)constDetailPage()),)3.3 自定义过渡动画classFadeScaleRouteTextendsPageRouteBuilderT{finalWidgetpage;FadeScaleRoute({requiredthis.page}):super(pageBuilder:(_,__,___)page,transitionsBuilder:(context,animation,secondaryAnimation,child){returnFadeTransition(opacity:animation,child:ScaleTransition(scale:Tweendouble(begin:0.9,end:1.0).animate(CurvedAnimation(parent:animation,curve:Curves.easeOut),),child:child,),);},transitionDuration:constDuration(milliseconds:250),reverseTransitionDuration:constDuration(milliseconds:200),);}四、路由栈管理4.1 路由栈常用操作操作方法场景入栈push进入新页面可返回出栈pop返回上一页替换pushReplacement登录成功后替换登录页清空入栈pushAndRemoveUntil退出登录后清空栈出栈到指定popUntil多级返回到主页查看栈顶canPop()判断是否可以返回4.2 嵌套 NavigatorclassMainPageextendsStatelessWidget{overrideWidgetbuild(BuildContextcontext){returnScaffold(body:Row(children:[NavigationPanel(),Expanded(child:Navigator(// 嵌套的 Navigator用于右侧内容区initialRoute:dashboard,onGenerateRoute:(settings){returnMaterialPageRoute(builder:(_)switch(settings.name){dashboardconstDashboardPage(),settingsconstSettingsPage(),_constNotFoundPage(),},);},),),],),);}}小结特性Navigator 1.0Navigator 2.0编程范式命令式声明式适用场景普通移动 AppWeb / 深链 / 复杂路由学习成本低高URL 支持有限完整第三方支持GoRouter / AutoRouteGoRouter推荐 下一节4.2 命名路由与参数传递

更多文章