300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Flutter系列之Navigator组件使用

Flutter系列之Navigator组件使用

时间:2022-03-21 07:46:48

相关推荐

Flutter系列之Navigator组件使用

PS:想做一件事很容易,真正去做一件事很困难。

同系列文章如下:

Flutter系列之Navigator使用详解Flutter系列之Flex布局详解Flutter系列之图片加载详解Flutter系列之Widget生命周期Flutter系列之混合开发Android篇Flutter系列之Platform Channel使用详解

Navigator 使用堆栈规则来管理 Widget,Navigator 记录了页面访问记录,可以使用 Navigator 来完成页面之间的跳转操作。

在 Android 开发中,我们平时说的跳转都是指的是 Activity 的跳转,也称为页面跳转,在 Fluter 中都是指的是 Route 的跳转,Android 中的页面在 Flutter 中对应 Route,Navigator 负责 Route 对象堆栈的管理,并提供管理堆栈的方法,如 Navigator.push 和 Navigator.pop。

如上 Flutter 提供了 Route 入栈、Route 出栈的方法,Android 中一些设备有返回键,这个返回键是兼容 Flutter 的 Navigator.push 和 Navigator.pop 方法,如果某些设备没有对应的返回键可以在 AppBar 中自行添加返回按钮, Scaffold 中已经添加了返回按钮,触发的时候会调用 Navigator.pop 操作,本文内容如下:

基本路由导航路由参数传递其他路由导航

基本路由导航

前面提到 Flutter 中使用堆栈来管理 Widget,入栈、出栈的方法分别是 Navigator.push 和 Navigator.pop,通过这两个方法来完成页面之间的跳转、回退操作。

Navigator.push

Navigator.push 用来执行 Route 的入栈操作,就可以通过指定的 Route 跳转到对应的页面了,方法如下:

/// 参数:(上下文,具体路由)static Future<T> push<T extends Object>(BuildContext context, Route<T> route) {return Navigator.of(context).push(route);}

使用 MaterialPageRoute 构建对应页面的路由,使用方式如下:

// 跳转到NavigatorPushPopPage_navigateToPage(context, NavigatorPushPopPage());/// Navigator.push/// 页面跳转_navigateToPage(BuildContext context, Widget widget) {Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {return widget;}));}

Navigator.pop

Navigator.pop 用来执行 Route 的退栈操作,即页面回退,可以添加可选参数 result 作为页面返回时携带的参数,方法如下:

/// 参数:(上下文,返回时携带的参数(可选参数))static bool pop<T extends Object>(BuildContext context, [ T result ]) {return Navigator.of(context).pop<T>(result);}

如下,点击 IconButton 退出当前页面:

IconButton(icon: Icon(Icons.arrow_back),onPressed: () => Navigator.pop(context)),

Navigator.pushnamed

Navigator.pushnamed 用来执行已命名 Route 的入栈操作,可以在通过可选参数 arguments 传递参数,方法如下:

/// 参数:(上下文,路由名称,携带的参数(可选参数))static Future<T> pushNamed<T extends Object>(BuildContext context,String routeName, {Object arguments,}) {return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);}

使用时首先在 MaterialApp 里面将对应的路由名称添加到路由表 routes 中,代码参考如下:

class MyApp extends StatelessWidget {// This widget is the root of your application.@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: HomePage(),routes: <String, WidgetBuilder>{// 对应路由/NavigatorPushNamedPageNavigatorPushNamedPage.routeName: (BuildContext context) =>NavigatorPushNamedPage(),},);}}/// page/// Navigator.pushNamed/// 使用已命名路由class NavigatorPushNamedPage extends StatelessWidget {static final routeName = '/NavigatorPushNamedPage';@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("Navigator.pushNamed"),centerTitle: true,),body: Center(child: Text("Navigator.pushNamed",style: TextStyle(fontSize: 18),),),);}}

然后就可以使用 Navigator.pushNamed 跳转到 NavigatorPushNamedPage 这个页面了,如下:

// 跳转到NavigatorPushNamedPage_navigatePushNamedPage(context, NavigatorPushNamedPage.routeName);/// Navigator.pushNamed/// 页面跳转_navigatePushNamedPage(BuildContext context, String routeName,[Object arguments]) {Navigator.pushNamed(context, routeName, arguments: arguments);}

以上就是 Flutter 中最基础的页面导航方式,无论是 Navigator.push 还是 Navigator.pushNamed 都是基于 NavigatorState 中的 push 方法实现的,NavigatorState 通过具体的 BuildContext 由 Navigator.of(context) 获取,NavigatorState 的 push 方法如下:

/// NavigatorState.pushFuture<T> push<T extends Object>(Route<T> route) {assert(!_debugLocked);assert(() { _debugLocked = true; return true; }());assert(route != null);assert(route._navigator == null);final Route<dynamic> oldRoute = _history.isNotEmpty ? _history.last : null;route._navigator = this;route.install(_currentOverlayEntry);_history.add(route);route.didPush();route.didChangeNext(null);if (oldRoute != null) {oldRoute.didChangeNext(route);route.didChangePrevious(oldRoute);}for (NavigatorObserver observer in widget.observers)observer.didPush(route, oldRoute);RouteNotificationMessages.maybeNotifyRouteChange(_routePushedMethod, route, oldRoute);assert(() { _debugLocked = false; return true; }());_afterNavigation(route);return route.popped;}

下面介绍一下 Fluter 中参数的传递,包括页面跳转时参数的传递以及页面回退是参数的传递。

路由参数传递

页面跳转过程中的参数传递包括页面跳转时携带参数和页面回退时携带参数。

Navigator.push携带参数

使用 Navigator.push 携带参数进行页面跳转,参数是通过对应页面的构造方法接收的,具体使用参考如下:

/// 跳转到NavigatorPushWithParamPage_navigateToPage(context,NavigatorPushWithParamPage(param: "this info from last page!",));/// Navigator.push/pop/// 页面跳转_navigateToPage(BuildContext context, Widget widget) {Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {return widget;}));}/// page/// Navigator.push携带参数class NavigatorPushWithParamPage extends StatelessWidget {// 参数final String param;NavigatorPushWithParamPage({this.param,});@overrideWidget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("Navigator.push携带参数"),centerTitle: true,),body: Center(child: Text("arguments:${this.param}",style: TextStyle(fontSize: 18),),),);}}

Navigator.pushNamed携带参数

从上文可知 Navigator.pushNamed(context,routrName,{arguments}) 方法参数中的可选参数 arguments 就是跳转要携带的参数,首先在 MaterialApp 下的 onGenerateRoute 中接收通过 arguments 传递过来的参数,如下:

class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Demo',theme: ThemeData(primarySwatch: Colors.blue,),home: HomePage(),// 参数接收onGenerateRoute: (RouteSettings settings) {if (settings.name == NavigatorPushNamedWithParamPage.routeName) {return MaterialPageRoute<String>(builder: (BuildContext context) {return NavigatorPushNamedWithParamPage(settings.arguments);});}else{return null;}},);}}

然后使用 Navigator.pushNamed 进行页面跳转,参数还是对应页面的构造方法接收,参考如下:

/// 跳转到NavigatorPushNamedWithParamPage_navigatePushNamedPage(context,NavigatorPushNamedWithParamPage.routeName,"this info from last page!");/// Navigator.pushNamed携带参数_navigatePushNamedPage(BuildContext context, String routeName,[Object arguments]) {Navigator.pushNamed(context, routeName, arguments: arguments);}/// page/// Navigator.pushNamed携带参数/// 使用已命名路由class NavigatorPushNamedWithParamPage extends StatelessWidget {static final String routeName = '/NavigatorPushNamedWithParamPage';final String info;NavigatorPushNamedWithParamPage(this.info);@overrideWidget build(BuildContext context) {return MaterialApp(home: Scaffold(appBar: AppBar(title: Text("Navigator.pushNamed携带参数"),centerTitle: true,),body: Center(child: Text("arguments:${this.info}",style: TextStyle(fontSize: 18),),),),);}}

页面返回时携带参数

从上文可知 Navigator.pop(context,[result]) 方法参数中的可选参数 result 就是页面回退时携带的参数,Navigator.push 会返回一个 Future 在 then 语句中处理页面回退的结果,具体使用参考如下:

/// 跳转到NavigatorPopWithParamPage_navigatePopWithParamPage(context, NavigatorPopWithParamPage());/// Navigator.pop返回时携带参数_navigatePopWithParamPage(BuildContext context, Widget widget) {Navigator.push<String>(context,MaterialPageRoute(builder: (BuildContext context) {return widget;})).then((result) {// 返回时携带参数处理Toast.show("Navigator.pop返回时携带参数:" + result, context);});}/// page/// Navigator.pop返回时携带参数class NavigatorPopWithParamPage extends StatelessWidget {@overrideWidget build(BuildContext context) {return WillPopScope(child: Scaffold(appBar: AppBar(title: Text("Navigator.pop返回时携带参数"),centerTitle: true,),body: Center(child: Text("Navigator.pop返回时携带参数",style: TextStyle(fontSize: 18),),),),onWillPop: () => _popBack(context));}/// 页面返回并设置返回参数,类似Android中的setResult方法_setResult(BuildContext context) {Navigator.pop(context, "this message from NavigatorPopWithParamPage!");}/// 统一处理返回键Future<bool> _popBack(BuildContext context) {_setResult(context);return Future.value(false);}}

其他路由导航

其他常用路由导航方式如下:

// 从Navigator中移除当前所在路由再跳转到新的路由,相当于finish再startActivityNavigator.popAndPushNamed// 根据指定的Route直接返回,在此之前的路由会被清除Navigator.popUntil// 跳转到新的Route,并将指定Route之前的的Route清空,pushNamedAndRemoveUntil与之类似Navigator.pushAndRemoveUntil// 页面替换,pushReplacementNamed与之类似Navigator.pushReplacement

其他与路由相关的操作方法就不一一列举了,可以查看相关 API。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。