Flutter路由和路由传值

基本路由

在Flutter中路由跳转是通过Navigator这个类进行操作的,它是一种堆栈的结构,主要有两个操作一个是push就是入栈操作,他会把当前页面放入栈顶并显示。还有一个就是pop,它会把当前页面进行出栈操作,并显示操作之后最上层的页面。

使用的时候我们需要先将需要跳转的页面文件进行导入,然后使用Navigator.push(context,MaterialPageRoute()),进行跳转。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
RaisedButton(
child: Text("跳转到搜索页面"),

onPressed: (){
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context){
return SearchPage();
}
)
);
},
color: Theme.of(context).accentColor,
textTheme: ButtonTextTheme.primary
)

当pop的时候

1
2
3
4
5
6
7
8
9
RaisedButton(
child: Text("跳转到搜索页面"),

onPressed: (){
Navigator.of(context).pop();
},
color: Theme.of(context).accentColor,
textTheme: ButtonTextTheme.primary
)

当然Navigator.of(context).push(xxx),Navigator.of(context).pop(xxx)也可以直接使用Navigator.push(context,xxx)或者Navigator.pop(context),其实原理都差不多只是后者封装了前者。

1
2
3
4
@optionalTypeArgs
static Future<T> push<T extends Object>(BuildContext context, Route<T> route) {
return Navigator.of(context).push(route);
}

基本路由传参

基本路由传参其实就是在需要传参的页面中的构造器加入需要传参的字段,然后通过构造器中的相应参数去传参。

1
2
3
Navigator.push(context, MaterialPageRoute(builder: (context){
return MyParam(title: '哈哈哈哈',);
}));

构造器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class MyParam extends StatelessWidget {
final String title;

MyParam({Key key, this.title}):super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test'),
),
body: Center(
child: Container(
height: 300.0,
width: 200.0,
decoration: BoxDecoration(
color: Colors.amber
),
child: Column(
children: <Widget>[
Text('$title'),
RaisedButton(
child: Text('返回'),
onPressed: (){
Navigator.pop(context);
},
)
],
)
),
),
);
}
}

当我们需要返回数据的时候(pop操作)

我们可以使用pop里面的result参数

1
2
3
4
@optionalTypeArgs
static bool pop<T extends Object>(BuildContext context, [ T result ]) {
return Navigator.of(context).pop<T>(result);
}

注意我们push方法返回的是一个Future,我们可以直接使用.then方法接受参数

1
2
3
4
5
6
7
8
9
Navigator.push<String>(context, new MaterialPageRoute(builder: (BuildContext context){

return new ThirdPage(title:"请输入昵称");

})).then( (String result){

//处理代码

});

命名路由

命名路由有点类似于Vue中的路由,我们需要将使用到的路由注册到MaterialApp中的routes参数中,这个routes参数是一个map

1
2
3
4
5
6
7
8
9
10
11
12
13
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
// home:Tabs(),
initialRoute: '/', routes: {
'/':(contxt)=>Tabs(),
'/search':(contxt) =>SearchPage(),
'/form': (context) => FormPage(),
},
);
}
}

initalRoute就是初始路由。

然后我们就可以使用Navigator.pushNamed(context,routeName)这个方法进行跳转页面了。

命名路由传参

命名路由传参主要借助于MaterialApp的onGeneratorRoute属性,这里面接受一个RouteFactory,其实返回的就是Route。

我们首先要删除routes属性(必须要,不然无法使用)。然后我们自己定义一个route的map。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class MyApp extends StatelessWidget {

// 我们需要在routes里面做些小变动,(context)需要变成(context,{arguments})
// 然后通过构造方法进行传参
final routes={
'/':(context)=>Tabs(),
'/form':(context)=>FormPage(),
'/product':(context)=>ProductPage(),
'/productinfo':(context,{arguments})=>ProductInfoPage(arguments:arguments),
'/search':(context,{arguments})=>SearchPage(arguments:arguments),
};

@override
Widget build(BuildContext context) {
return MaterialApp(
// home:Tabs(),
initialRoute: '/', //初始化的时候加载的路由
onGenerateRoute: (RouteSettings settings) {
// 统一处理
final String name = settings.name;
final Function pageContentBuilder = routes[name];
if (pageContentBuilder != null) {
if (settings.arguments != null) {
final Route route = MaterialPageRoute(
builder: (context) =>
pageContentBuilder(context, arguments: settings.arguments));
return route;
}else{
final Route route = MaterialPageRoute(
builder: (context) =>
pageContentBuilder(context));
return route;
}
}
}
);
}
}

当然,我们的Navigator也需要变动

1
2
3
4
//路由跳转
Navigator.pushNamed(context, '/search',arguments: {
"id":123
});

这里我们需要增加argument参数(这是原本方法自带的参数)

-------------本文结束感谢阅读-------------