简介
上篇文章咱们讲到了flutter中navigator的根本用法,咱们能够应用它的push和pop办法来进行Router之间的跳转。
在flutter中一个Router就是一个widget,然而在Android中,一个Router就是Activity,在IOS中,一个Router是一个ViewController。
Router除了之前讲过的push和pop办法之外,还有一些更加高级的用法,一起来看看吧。
named routes
尽管在flutter中navigator将routers以stack的模式进行存储,能做的也只是push和pop操作,然而事实上Router是能够有名字的。
想想也是,如果Router没有名字的话,那么如何顺利进行跳转呢?不可能每次都new一个Router进去吧。
navigator有一个办法叫做Navigator.pushNamed()用来将带名字的Router压入堆栈,咱们来看下它的定义:
static Future<T?> pushNamed<T extends Object?>( BuildContext context, String routeName, { Object? arguments, }) { return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments); }
这个办法须要传入一个context和对应的routeName,同时还能够带一些参数。
那么怎么用这个办法呢?
首先咱们须要定义一些Router,比如说在创立MaterialApp的时候能够传入routes参数,来设置named Routers:
MaterialApp( title: '这是named Routers', initialRoute: '/firstPage', routes: { '/firstPage': (context) => const FirstPage(), '/secondPage': (context) => const SecondPage(), },)
下面的代码中咱们别离定了两个routers,别离是firstPage和secondPage,他们别离对应一个自定义的widget。
定义好Router之后,咱们就能够向上面这样应用了:
onPressed: () { Navigator.pushNamed(context, '/secondPage');}
如果要返回第一个页面的话,那么能够调用Navigator.pop办法来实现:
onPressed: () { Navigator.pop(context);}
给named route传参数
在上一节咱们讲到pushNamed的时候,还介绍了它还能够接管参数arguments。从定义上能够看到arguments的类型是Object对象,也就是说任何对象都能够作为named route的参数。
那么咱们先定义一个对象如下:
class TestArguments { final String name; final String description; TestArguments(this.name, this.description);}
接下来咱们须要创立一个可能承受这个参数的Routers。
因为所有的Routers都是Widget,所以咱们须要创立一个Widget,并在这个widget外部接管传入的参数。
在flutter中有两种传递参数的形式,你能够应用ModalRoute.of(),也能够应用onGenerateRoute()。
咱们先来看下ModalRoute.of的定义:
static ModalRoute<T>? of<T extends Object?>(BuildContext context) { final _ModalScopeStatus? widget = context.dependOnInheritedWidgetOfExactType<_ModalScopeStatus>(); return widget?.route as ModalRoute<T>?; }
它接管一个context参数,而后返回一个route对象。
具体的用法如下:
class FirstPage extends StatelessWidget { const FirstPage({super.key}); static const routeName = '/firstPage'; @override Widget build(BuildContext context) { final args = ModalRoute.of(context)!.settings.arguments as TestArguments; return Scaffold( appBar: AppBar( title: Text(args.name), ), body: Center( child: Text(args.description), ), ); }}
除了应用ModalRoute之外,还能够在onGenerateRoute()办法中进行参数传递。onGenerateRoute是在Route生成的时候触发的:
MaterialApp( onGenerateRoute: (settings) { if (settings.name == FirstPage.routeName) { final args = settings.arguments as TestArguments; return MaterialPageRoute( builder: (context) { return TestArguments( title: args.title, message: args.message, ); }, ); } return null; },)
onGenerateRoute接管一个settings对象,咱们须要在settings对象中设置对应的name和arguments属性。所以咱们须要这样调用:
Navigator.pushNamed( context, FirstPage.routeName, arguments: TestArguments( '测试', '这是一个named Route', ), );
从Screen返回值
有时候咱们须要从一个Screen返回到之前的Screen,并且不是简略的返回,咱们还心愿晓得前一个screen返回了什么后果,而后能够依据前一个screen返回的不同后果来进行不同的解决。
这个时候就须要用到Navigator.pop的传参性能了。
比方咱们在第一个页面中点击了按钮,跳转到第二个页面:
final result = await Navigator.push( context, MaterialPageRoute(builder: (context) => const SecondScreen()), );
这里咱们应用到了Navigator.push办法,并且返回了一个result的值。
咱们能够应用这个值来进行一些逻辑判断。
那么这个result的值是哪里传递过去的呢?
没错,就是SecondScreen中的Navigator.pop办法:
Navigator.pop(context, 'Yes');
这里的'Yes'就会传递给result供咱们进行逻辑判断。
向Screen传值
有时候咱们须要在页面跳转的过程中传递一些参数,那么怎么能力实现Screen之间的参数传递呢?
因为在flutter中所有的Routers都是Widget,所以咱们能够在跳转到新的页面的时候间接将参数以构造函数的形式传递给Routers Widget。
比方咱们有上面的Screen Widget:
class NameScreen extends StatelessWidget { const NameScreen({super.key, required this.name}); final String name; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('NameScreen'), ), body: ... ; }}
想要传值给它,能够在onTap办法中这样写:
onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => NameScreen(name: 'what is your name?'), ), );
总结
以上就是Navigator的更加高级的用法,咱们能够通过Navigator来进行数据传递等操作,从而实现更加简单的页面性能。