跟Web页或者原生APP同样,咱们在使用Flutter 开发APP时也会涉及到多页面之间的跳转、参数传递、参数回传等业务,
Flutter路由
能知足上述咱们提到的全部业务类型,此外咱们也能够结合Flutter动画
给路由跳页时添加个性化的跳页动画操做,我会在后续Flutter动画
章节中具体讲解。经过本节专题,读者不单单能够本身动手作一些简单的UI,还能利用Fluttter 路由
结合以前的课程分享作一些简单的多页面Flutter App。java
在Flutter中路由分为静态路由
跟动态路由
两种:Flutter中所谓的静态路由指的是须要提早把各个须要跳转的页面路径注册在routes: <String, WidgetBuilder> {}
中,且静态路由不支持向下一个页面传递参数,可是能够接收下一个页面的返回值
。 动态路由使用就相对来讲比较灵活一点,动态路由一样支持向下一个页面传递参数,并且在使用时不须要咱们提早规划好页面路径,只须要在具体跳页逻辑中本身去构造MaterialPageRoute
对象来完成页面跳转,或者用PageRouterBuilder
来自定义路由跳转时的动画,关于路由跳转动画
我会在Flutter动画章节中具体讲解,固然动态路由一样也支持页面参数回传。app
场景一:点击A页面中的按钮跳转到B页,不涉及到数据传递以及回传less
效果图 ide
MaterialApp
中的routes中提早注册路由
new MaterialApp(
home: new FlutterDemo(),
routes: <String, WidgetBuilder>{
'router/new_page': (_) => new StaticNavigatorPage()
}));
复制代码
A页面代码:测试
import 'package:flutter/material.dart';
import 'package:flutter_app/pages/simpleWidget/navigator/StaticNavigatorPage.dart';
void main() {
runApp(new MaterialApp(
home: new FlutterDemo(),
routes: <String, WidgetBuilder>{
'router/new_page': (_) => new StaticNavigatorPage()
}));
}
class FlutterDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Flutter进阶之旅"),
),
body: new Center(
child: new RaisedButton(
child: new Text("静态路由跳页"),
onPressed: () {
Navigator.of(context)
.pushNamed('router/new_page'); //这里必定要保证跳页的路由路径跟上面注册的路径一致
})),
);
}
}
复制代码
B页面代码:动画
import 'package:flutter/material.dart';
class StaticNavigatorPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("静态路由页"),
),
floatingActionButton: new FloatingActionButton(
onPressed: () {
Navigator.of(context).pop();
},
child: new Text("返回"),
),
body: new Center(
child: Text("静态路由能够传入一个routes参数来定义路由。可是这里定义的路由是静态的,"
"它不能够向下一个页面传递参数,利用push到一个新页面,pushNamed方法是有一个Future的返回值的"
",因此静态路由也是能够接收下一个页面的返回值的。可是不能向下一个页面传递参数"),
),
);
}
}
复制代码
上述借助路由跳页过程当中咱们注意到,大概分如下几步: 1.注册路由且保证路由的惟一性 2.跳页时使用Navigator.of(context).pushNamed('路由地址');
3.使用Navigator.of(context).pop();
结束当前页ui
场景二:点击A页面上的按钮跳页到B页面,在B页面销毁后A页面接收到B页面回传回来的值而且显示在
AlertDialog
上this
效果图 spa
showDialog
显示在
Dialog
上
import 'package:flutter/material.dart';
import 'package:flutter_app/pages/simpleWidget/navigator/StaticNavigatorPageWithParams.dart';
void main() {
runApp(
new MaterialApp(home: new FlutterDemo(), routes: <String, WidgetBuilder>{
'router/new_page_with_callback': (_) => new StaticNavigatorPageWithResult()
}));
}
class FlutterDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Flutter进阶之旅"),
),
body: new Center(
child: new RaisedButton(
child: new Text("静态路由接收下一页返回值"),
onPressed: () {
Navigator.of(context)
.pushNamed('router/new_page_with_callback')
.then((value) {
showDialog(
context: context,
child: new AlertDialog(
content: new Text(value),
));
});
})),
);
}
}
复制代码
B页面代码:code
从效果图中能够看到,当我点击B页面中间的按钮时会把数据回传给上一页,可是直接点击导航栏左上角的返回按钮回到A页面时并不会把数据传递给上一个页面,这里是由于我在B页面的按钮上pop页面出栈的时候把参数放进里面做为了参数传递,pop()
可接收一个Object对象做为参数传递
Navigator.of(context).pop(T extends Object);
复制代码
这就告诉咱们当咱们须要给上一个页面回传数据的时候可直接借助pop传递Navigator.of(context).pop("页面结束后返回的数据");
,不须要传值的时候直接返回空对象Navigator.of(context).pop()
便可。
import 'package:flutter/material.dart';
class StaticNavigatorPageWithResult extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("静态路由带返回参数"),
),
body: new Center(
child: new OutlineButton(
onPressed: () {
Navigator.of(context).pop("页面结束后返回的数据");
},
child: Text("点我返回上个页面结束后返回的数据"),
),
),
);
}
}
复制代码
文章的开头咱们提到借助动态路由能够向下一个页面传递参数,一样也能够接收新页面回传回来的数据。下面我模拟两个使用动态路由的场景,既然动态路由能够传值那就确定能够不传值跳页,我就不模拟动态路由不传值跳页的例子了,读者借助静态路由的样例自行测试便可,咱们主要讲解一下借助动态路由传值的例子。
场景三:点击A页面中的按钮,把用户名跟密码传递给下一个页面B页面,B页面处理完接收到的数据后把结果回传给A页面,A页面中把从B页面回传回来的数据显示在Dialog上。
模拟效果图
MaterialApp
中的router中提早注册路由路径,只须要在使用
Navigator.push
传入MaterialPageRoute对象便可
Navigator.push(
context,
new MaterialPageRoute(
//_表明参数为空
builder: (_) => new DynamicNaviattionPage(
username: "xiedong",
password: "123456",
)));
复制代码
A页面代码:
import 'package:flutter/material.dart';
import 'package:flutter_app/pages/simpleWidget/navigator/DynamicNavigationPage.dart';
void main() {
runApp(new MaterialApp(home: new FlutterDemo()));
}
class FlutterDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Flutter进阶之旅"),
),
body: new Center(
child: new RaisedButton(
onPressed: () {
Navigator.push(
context,
new MaterialPageRoute(
//_表明参数为空
builder: (_) => new DynamicNaviattionPage(
username: "xiedong",
password: "123456",
))).then((value) {
showDialog(
context: context,
child: new AlertDialog(
content: new Text(value),
));
});
},
child: new Text("动态路由传参"),
)));
}
}
复制代码
B页面代码:
import 'package:flutter/material.dart';
class DynamicNaviattionPage extends StatelessWidget {
var username;
var password;
DynamicNaviattionPage({Key key, this.username, this.password})
: super(key: key);
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("动态路由"),
),
body: new Center(
child: new Column(
children: <Widget>[
new MaterialButton(
onPressed: () {
Navigator.pop(context, "未查询到改该用户信息");
},
child: new Text("点我返回"),
color: Colors.lightGreen,
),
new Text("上页传递过来的username $username"),
new Text("上页传递过来的password $password"),
],
),
),
);
}
}
复制代码
关于路由重点总结