在安卓和苹果设备上都有页面跳转的操作,flutter中是使用Navigator来管理页面之间的跳转的。在万物皆Widget的flutter中,Navigator自然也没有逃过成为一个widget的命运,它属于StatefulWidget的子类。Navigator负责管理页面的的堆栈,并提供管理堆栈的方法,像push(显示页面)、pop(关闭页面);
Navigator显示页面通常用这几种方式:
一、使用一个builder函数创建MaterialPageRoute实例,代码如下:
children: <Widget>[
RaisedButton(
//调用_testPush方法
onPressed: _testPush, child: Text("跳转到第二个页面"),),
Text(_result, style: TextStyle(fontSize: 20),)
],
void _testPush() {
Navigator.push(context, new MaterialPageRoute(builder: (context) {
return new SecondViewWidget("from first view");
}, ),);
}
class SecondViewWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(appBar: AppBar(title: Text("SecondViewWidget"),),
body: Center(child: Column(
mainAxisAlignment: MainAxisAlignment.center, children: <Widget> [
Text("second View", style: TextStyle(fontSize: 20, color: Colors.blue),)
Text("$_value", style: TextStyle(fontSize: 20, color: Colors.blue),),
RaisedButton(onPressed: _back(context), child: Text("返回上一页"),),
],),),);
}
}
_back(BuildContext context) {
Navigator.pop(context, "hello");
}
从上面代码可以看出,当需要从第一个页面向第二个页面传递参数时,是通过第二个页面的构造函数来传递的,这个容易理解。那么当第二个页面结束时,需要从第二个页面向第一个页面传参数时怎么做呢?当要退出页面时调用Navigator.pop(context, "hello");方法。这个方法的第二个参数就是要向上一个页面返回的结果值,返回后只需在上个页面接收就可以了。下面来看一下上一个页面是如何接收数据的:
void _testPush() async {
String result = await Navigator.push(
context, new MaterialPageRoute<String>(builder: (context) {
return new SecondViewWidget("from fist value");
}, maintainState: false),);
if (result != null) {
print("result:$result");
}
}
依然是上面跳转页面的方法,区别在于等待push方法返回一个结果值,这个结果值就是第二个页面返回来的结果。
二、使用命名方式来管理页面
把页面名称使用类似路径的结构(例如,'/a/b/c')。应用程序的主页路径默认为'/'。MaterialApp可以使用Map<String, WidgetBuilder>创建,它将路由的名称映射到将创建它的builder函数。MaterialApp使用这个映射为其导航器的onGenerateRoute回调创建一个值。
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
//把所有的页面路径放到集合中
routes: {
"/": (BuildContext contxt) => new MyHomePage(title: "first page"),
"/second": (BuildContext context) => SecondViewWidget()},
theme: ThemeData(
primarySwatch: Colors.blue,
),
//home不能与“/”混用,否则会报错的
// home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
children: <Widget>[
RaisedButton(
onPressed: _testPush3, child: Text("跳转到第二个页面"),),
],
void _testPush3() {
Navigator.pushNamed(context, "/second", arguments: "from fistView");
}
这种方式的跳转,页面之间的传参和第一种不太一样了Navigator.pushNamed(context, "/second", arguments: "from fistView");
arguments对应的就是要传过去的值,下面看在第二个页面中如何接收:
class SecondViewWidget extends StatelessWidget {
SecondViewWidget(this._value);
String _value;
@override
Widget build(BuildContext context) {
String value = ModalRoute.of(context) .settings .arguments;
print("value:$value");
........
}
}
通过这句String value = ModalRoute.of(context) .settings .arguments;获取到值,需要注意的是value的类型需要传过来的类型一致。
从第二个页面返回数据到第一个页面的方式同上述第一种情况。
三、在安卓原生的应用中页面切换通常会加入动画,那么在flutter中也可以用PageRouteBuilder的方式来完成切换动画。有请代码君:
void _testPush2() {
Navigator.push(context,
new PageRouteBuilder(pageBuilder: (context, _, __) {
return new SecondViewWidget();
}, transitionsBuilder: (context, Animation<double> animation, _,
Widget child) {
return FadeTransition(opacity: animation,
child: new RotationTransition(
turns: Tween<double>(begin: 0.5, end: 1.0).animate(animation),
child: child,));
},
transitionDuration: Duration(seconds: 1)));
}
由于是初学flutter有不对的地方,烦请大家帮忙指正,共同学习。