Flutter中使用
Navigator
可以完成路由的路由的跳转。
一、Navigator
1.1 Navigator的使用
- 首先创建两个页面:
main.dart
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter demo')
),
body: RouteDemo(),
),
);
}
}
class RouteDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Center(
child: RaisedButton(
child: Text('打开新的路由'),
onPressed: () {},
),
);
}
}
page.dart:
import 'package:flutter/material.dart';
class PageRouteDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('pageRoute'),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
}),
),
body: Center(
child: Text('pageRoute'),
),
);
}
}
- 要实现从
main.dart
跳转至page.dart
,需借助Navigator
,现在对main.dart
中的按钮点击事件中添加如下代码:
// 页面入栈
Navigator.push(context, MaterialPageRoute(
builder: (context) => PageRouteDemo(),
));
- 现在点击按钮,就可以跳转到
page.dart
页面了,但是我们点击page.dart
上方的返回按钮是没有反应的,此时我们在page.dart
中的返回图标中添加点击事件:
// 页面出栈
Navigator.pop(context);
1.2 使用Navigator传递参数
在页面跳转时,难免会传递一些参数,那么使用Navigator
怎样传递参数呢。这里有两种方法,其中一种是通过PageRouteDemo
的构造函数传递,另一种是通过设置MaterialPageRoute
中的settings
属性。:
import 'package:flutter/material.dart';
class PageRouteDemo extends StatelessWidget {
String param;
PageRouteDemo({this.param});
@override
Widget build(BuildContext context) {
// 获取来自settings属性的数据
Map map = ModalRoute.of(context).settings.arguments;
// TODO: implement build
return Scaffold(
appBar: AppBar(
title: Text('pageRoute'),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
}),
),
body: Center(
child: Text('通过构造函数传递: $param;settings参数传递:${map["id"]}'),
),
);
}
}
Navigator.push(context, MaterialPageRoute(
builder: (context) => PageRouteDemo('来自上个页面的数据'),
settings: RouteSettings(arguments: {"id": 2123})
));
在调用Navigator.push
时直接将参数传入PageRouteDemo构造函数当中即可。那么如果是返回的时候要传递数据呢?其实Navigator.pop
是可以传入第二个参数,这个参数就是当前页面要返回给上一个页面的数据,然后在上个页面使用Navigator.push
接受这个数据。
Navigator.pop(context, '页面返回时传递的数据');
main.dart中接受数据:
RaisedButton(
child: Text('打开新的路由'),
onPressed: () async {
String result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PageRouteDemo(param:'来自上个页面的数据'),
// fullscreenDialog: false,
settings: RouteSettings()));
if (result != null) {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text(result),
));
}
},
),
二、MaterialPageRoute
MaterialPageRoute
继承自PageRoute
类,PageRoute
类是一个抽象类,表示占有整个屏幕空间的一个模态路由页面,它还定义了路由构建及切换时过渡动画的相关接口及属性。MaterialPageRoute
是Material组件库的一个Widget,它可以针对不同平台,实现与平台页面切换动画风格一致的路由切换动画:
- Andriod:当打开新页面时,页面会从底部滑动到顶部。
- iOS:当打开新页面时,页面会从右侧滑动进入屏幕。
2.1 MaterialPageRoute构造函数
MaterialPageRoute({
@required this.builder, // 是一个WidgetBuilder类型的回调函数,它的作用是构建路由页面的具体内容,返回值是一个widget
RouteSettings settings, // 包含路由的配置信息,如路由名称、是否初始路由(首页)
this.maintainState = true, // 默认情况下,当入栈一个新路由时,原来的路由任然会被保存在内存中,如果想在路由没用的时候释放其所占用的所有资源,可以设置maintainState为false
bool fullscreenDialog = false, //表示新的路由页面是否是一个全屏的模态对话框,在iOS中,如果fullscreenDialog为true,新页面将会从屏幕底部滑入
})
三、命名路由
通过MaterialApp
中的routes
属性注册一个路由表,调用Navigator.pushNamed
方法指定要跳转的路由,同样可以实现页面跳转。示例代码如下:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
'/page': (context) => PageRouteDemo()
},
home: Scaffold(
appBar: AppBar(
title: Text('Flutter demo')
),
body: RouteDemo(),
),
);
}
}
class RouteDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return Center(
child: RaisedButton(
child: Text('打开新的路由'),
onPressed: () {
Navigator.pushNamed(context, '/page', arguments: {'id': 324});
},
),
);
}
}