跟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"),
],
),
),
);
}
}
複製代碼
關於路由重點總結