Flutter 頁面如何跳轉(zhuǎn)诞外?
一、Navigator介紹
Navigator 繼承自 StatefulWidget灾票,它也是小組件峡谊,它有很多相關(guān)靜態(tài)函數(shù),可以幫我們達(dá)到頁面跳轉(zhuǎn)和數(shù)據(jù)交互的功能:
push 將設(shè)置的router信息推送到Navigator上刊苍,實現(xiàn)頁面跳轉(zhuǎn)既们。
of 主要是獲取Navigator最近的Widget。
pop 導(dǎo)航到新頁面正什,或者返回到上個頁面啥纸。
canPop 判斷是否可以導(dǎo)航到新頁面
maybePop 可能會導(dǎo)航到新頁面
popAndPushNamed 指定一個路由路徑,并導(dǎo)航到新頁面婴氮。
popUntil 反復(fù)執(zhí)行pop 直到該函數(shù)的參數(shù)predicate返回true為止斯棒。
pushAndRemoveUntil 將給定路由推送到Navigator,刪除先前的路由主经,直到該函數(shù)的參數(shù)predicate返回true為止荣暮。
pushNamedAndRemoveUntil 將命名路由推送到Navigator,刪除先前的路由旨怠,直到該函數(shù)的參數(shù)predicate返回true為止渠驼。
pushNamed 將命名路由推送到Navigator。
pushReplacement 路由替換。
pushReplacementNamed 替換路由操作迷扇。推送一個命名路由到Navigator百揭,新路由完成動畫之后處理上一個路由。
removeRoute 從Navigator中刪除路由蜓席,同時執(zhí)行Route.dispose操作器一。
removeRouteBelow 從Navigator中刪除路由,同時執(zhí)行Route.dispose操作厨内,要替換的路由是傳入?yún)?shù)anchorRouter里面的路由祈秕。
replace 將Navigator中的路由替換成一個新路由。
replaceRouteBelow 將Navigator中的路由替換成一個新路由雏胃,要替換的路由是是傳入?yún)?shù)anchorRouter里面的路由请毛。
二、Navigator使用
2.1 push && pop
- 代碼
//跳轉(zhuǎn)下一頁
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage())
);
context: 上下文
MaterialPageRoute: 必須要傳入一個閉包函數(shù) WidgetBuilder瞭亮,該閉包函數(shù)的參數(shù)是 BuildContext對象.
//返回上一頁
Navigator.pop(context);
2.2 pushNamed
- 代碼
Navigator.of(context).pushNamed('/page2');
此種方法只是簡單的將我們需要進(jìn)入的頁面push到棧頂方仿,以此來顯示當(dāng)前頁面,
其參數(shù)是一個字符串類型,傳入的是頁面對應(yīng)的路由名稱
該路由名稱需要在程序主入口中進(jìn)行定義统翩。定義方法為:
void main() {
runApp(
new MaterialApp(
home: new Page1(),
routes: <String, WidgetBuilder> {
'/page1': (BuildContext context) => new Page1(),
'/page2' : (BuildContext context) => new Page2(),
'/page3' : (BuildContext context) => new Page3(),
},
)
);
}
使用:Navigator.of(context).pushNamed('/page1');
直接進(jìn)入screen1頁面(每次都將新建一個新的頁面)
2.2 pushReplacementNamed && pushReplacement
- 代碼
Navigator.of(context).pushReplacementNamed('/page3');
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => Page3()));
指把當(dāng)前頁面在棧中的位置替換成跳轉(zhuǎn)的頁面(替換導(dǎo)航器的當(dāng)前路由仙蚜,通過推送路由[routeName]),當(dāng)新的頁面進(jìn)入后厂汗,之前的頁面將執(zhí)行dispose方法委粉。
即比如當(dāng)前從頁面1進(jìn)入頁面2,在頁面2使用 pushReplacementNamed 進(jìn)入頁面3娶桦,當(dāng)進(jìn)入了頁面3后贾节,頁面2將執(zhí)行dispose方法,此時在頁面3返回時趟紊,會回到頁面1.
使用場景:
例如從SplashScreen到HomeScreen氮双。它應(yīng)該只顯示一次,用戶不應(yīng)該再從主屏幕回到它霎匈。在這種情況下戴差,由于我們將要進(jìn)入一個全新的屏幕,
我們可能想要使用這個方法來實現(xiàn)它的enter animation屬性铛嘱。
2.2 popAndPushNamed
- 代碼
Navigator.popAndPushNamed(context, '/page3');
Navigator.of(context).popAndPushNamed('/page3');
指將當(dāng)前頁面pop暖释,然后跳轉(zhuǎn)到指定頁面(將當(dāng)前路由彈出導(dǎo)航器,并將命名路由推到它的位置墨吓。)
使用場景:
例如在購物應(yīng)用中球匕,有產(chǎn)品列表,用戶在產(chǎn)品列表中可以通過篩選帖烘,來進(jìn)一步選擇商品亮曹,在這個過程中,用戶點擊篩選按鈕時,會進(jìn)入篩選條件選擇界面照卦,當(dāng)用戶點擊
確定篩選按鈕時式矫,應(yīng)pop掉篩選界面,并使用新的篩選條件進(jìn)入產(chǎn)品列表役耕。這種情況popAndPushNamed就比較合適了采转。
2.3 pushNamedAndRemoveUntil && pushAndRemoveUntil
-
方式一
Navigator.of(context).pushNamedAndRemoveUntil( '/page3', (Route<dynamic> route) => false );
Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (context) => Page4()), (Route<dynamic> route) => false, );
指將指定的頁面 page3 加入到路由中,然后將其他所有的頁面全部pop, (Route<dynamic> route) => false 將確保刪除推送路線之前的所有路線瞬痘。
這時候?qū)⒋蜷_一個新的 page3 頁面, 實際上就是將新的Page3 重新設(shè)置成了根(root)
使用場景:
例如當(dāng)用戶點擊了退出登錄時故慈,我們需要進(jìn)入某一個頁面(比如點退出登錄后進(jìn)入了登錄頁),這個時候用戶點擊返回時不應(yīng)該能進(jìn)入任何一個頁面框全,這種情況就可以使用察绷。
-
方式二
Navigator.of(context).pushNamedAndRemoveUntil( '/page4', ModalRoute.withName('/page1') );
缺點是必須page1有被注冊過 Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (context) => Page4()), ModalRoute.withName('/page1'), );
指將指定的頁面加入到路由中,然后將之前的路徑移除知道指定的頁面為止(將具有給定名稱的路由推到導(dǎo)航器上津辩,然后刪除所有路徑前面的路由直到'predicate'返回true為止克婶。)即會移除掉 /page1 和 /page4 之間的所有頁面。
使用場景:
例如一個購物應(yīng)用程序的例子!或者任何需要支付交易的應(yīng)用程序丹泉。因此,在這些應(yīng)用程序中鸭蛙,一旦用戶完成了支付事件摹恨,所有與交易或購物車相關(guān)的屏幕都應(yīng)該從堆棧中刪除,用戶應(yīng)該進(jìn)入到支付確認(rèn)頁面娶视。單擊back按鈕應(yīng)將它們返回到產(chǎn)品列表或主屏幕晒哄。
使用實例:
1-->2-->3,3到4時使用Navigator.pushNamedAndRemoveUntil(context,"/page4",ModalRoute.withName('/page1'));
這時候如果在頁面4點擊返回,將會返回到1肪获。
1-->2-->3,3到4時使用Navigator.pushNamedAndRemoveUntil(context,"/page4",ModalRoute.withName('/'));
這時候如果在頁面4點擊返回寝凌,將會直接回到root頁面。
1-->2-->1-->2-->3,3到4時使用Navigator.pushNamedAndRemoveUntil(context,"/page4",ModalRoute.withName('/page1'));
這時候如果在頁面4點擊返回孝赫,將會回到第二個1頁面较木。
2.3 popUntil
- 代碼
Navigator.popUntil(context, ModalRoute.withName('/page2'));
使用場景:
有些應(yīng)用場景下,用戶可能不得不填寫一個由三部分組成的長表單青柄,該表單可能在移動應(yīng)用程序的三個連續(xù)屏幕中顯示》フ現(xiàn)在在表單的第三個頁面,用戶決定取消填寫表單致开。用戶單擊Cancel峰锁,就會彈出所有之前的與表單相關(guān)的屏幕,并將用戶帶回主屏幕双戳,從而丟失所有與表單相關(guān)的數(shù)據(jù)(在這種情況下虹蒋,這是我們想要的)。我們不會在這里推出任何新東西,只是回到以前的路線魄衅。
2.4 maybePop && canPop
- 代碼
Navigator.of(context).maybePop();
maybePop 會自動進(jìn)行判斷峭竣,如果當(dāng)前頁面pop后,會顯示其他頁面徐绑,不會出現(xiàn)問題邪驮,則將執(zhí)行當(dāng)前頁面的pop操作,否則將不執(zhí)行。
Navigator.of(context).canPop();
canPop 判斷當(dāng)前頁面能否進(jìn)行pop操作傲茄,并返回bool值
Navigator.of(context).pop();
直接退出當(dāng)前頁面
三毅访、頁面參數(shù)傳遞
-
參數(shù)傳遞
傳參的方式很簡單,在需要接收參數(shù)的頁面進(jìn)行參數(shù)定義盘榨,并加入其構(gòu)造函數(shù)中喻粹,在跳轉(zhuǎn)到該頁面時,使用MaterialPageRoute并在頁面中傳入?yún)?shù)即可草巡。
String params;
Navigator.push(
context,
MaterialPageRoute(builder: (context) => TestPage(params))
);
接收參數(shù)
class TestPage extends StatelessWidget {
final String userName;
mainPage(this.userName);
@override
Widget build(BuildContext context) {
print(userName);
return Container();
}
}
帶返回值的頁面跳轉(zhuǎn):
String userName = "xxx";
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Page5(userName)))
.then((data){
result =data;
print(result);
}
);
class Page5 extends StatelessWidget {
final String userName;
Page5(this.userName);
@override
Widget build(BuildContext context) {
print(userName);
return Container(
child: RaisedButton(
child: Text('下一頁'),
onPressed: (){
Navigator.of(context).pop('page5返回的參數(shù)');
},
);
}
然后 Page5 中守呜,在返回時使用:Navigator.of(context).pop('params');
在pop中寫上返回的的值,這時候在上方的then中即可得到返回的數(shù)據(jù)山憨。