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});
},
),
);
}
}