??????小菜最近在抽時(shí)間學(xué)習(xí) Flutter,從零開(kāi)始偏形,一步一步走的都很艱難,前幾天搭了一個(gè)基本的【登錄】頁(yè)面寡痰,現(xiàn)在學(xué)習(xí)下一步抗楔,頁(yè)面之間的跳轉(zhuǎn);今天小菜整理一下 Flutter 測(cè)試過(guò)程中常用的頁(yè)面跳轉(zhuǎn)方式拦坠。
??????最權(quán)威的資料永遠(yuǎn)是 Flutter 官網(wǎng)连躏,很精華,只可惜小菜英語(yǔ)水平太次贞滨,讀起來(lái)有點(diǎn)吃力入热。但小菜了解到,Flutter 中跳轉(zhuǎn)一定要用到 Navigator晓铆,就像是 Android 中的 Intent勺良;小菜理解為就是一個(gè)棧,進(jìn)進(jìn)出出跟 Android 是很類(lèi)似的骄噪,而 Flutter 也很直接尚困,關(guān)鍵詞就是 push 和 pop,小菜分別從這兩個(gè)關(guān)鍵詞來(lái)測(cè)試 Flutter 頁(yè)面間的跳轉(zhuǎn)链蕊。
push 入棧
1. 靜態(tài)注冊(cè)跳轉(zhuǎn) Using named navigator routes
??????使用靜態(tài)注冊(cè)方式時(shí)事甜,需要在主頁(yè)面的方法中添加 rount,小菜感覺(jué)有點(diǎn)像 AndroidManifest 中 intnt-filter 中靜態(tài)注冊(cè)滔韵;而 Flutter 中的 => 方法很像 Kotlin 中的 -> 減少代碼行逻谦。
routes: {
'forgetPwdRoute': (BuildContext context) => new ForgetPwdPage(),
'homeRoute': (BuildContext context) => new HomePage(),
},
1.1 pushNamed 方法單純跳轉(zhuǎn)頁(yè)面
??????Navigator.pushNamed 包含兩個(gè)參數(shù),第一個(gè)小菜理解為上下文環(huán)境陪蜻,第二個(gè)參數(shù)為靜態(tài)注冊(cè)的對(duì)應(yīng)的頁(yè)面名稱(chēng)邦马;如:
onTap: () {
Navigator.pushNamed(context, "forgetPwdRoute");
},
1.2 pushNamedAndRemoveUntil 跳轉(zhuǎn)頁(yè)面并銷(xiāo)毀當(dāng)前頁(yè)面
??????Navigator.pushNamedAndRemoveUntil 包含三個(gè)參數(shù),第一個(gè)小菜理解為上下文環(huán)境囱皿,第二個(gè)參數(shù)為靜態(tài)注冊(cè)的對(duì)應(yīng)的頁(yè)面名稱(chēng)勇婴,第三個(gè)參數(shù)為跳轉(zhuǎn)后的操作,route == null 為銷(xiāo)毀當(dāng)前頁(yè)面嘱腥;如:
onPressed: () {
Navigator.pushNamedAndRemoveUntil(context, "homeRoute", (route) => route == null);
}
??????Tips: 如果在 HomePage 頁(yè)面中調(diào)用 Navigator.pop(context); 會(huì)出現(xiàn)半個(gè)黑屏情況耕渴,所以小菜并不建議這種方式銷(xiāo)毀頁(yè)面,但是點(diǎn)擊返回按鈕是正常的齿兔。
2. 動(dòng)態(tài)注冊(cè)跳轉(zhuǎn)
2.1 push 方法單純跳轉(zhuǎn)頁(yè)面
??????Navigator.push 向下個(gè)頁(yè)面跳轉(zhuǎn)時(shí)橱脸,可以傳遞參數(shù)础米,自己生成頁(yè)面對(duì)象;如:
onPressed: () {
Navigator.push<Object>(context,
new MaterialPageRoute(
builder: (BuildContext context) {
return new HomePage();
},
),
);
}
2.2 push 方法單純跳轉(zhuǎn)頁(yè)面并傳遞參數(shù)
onPressed: () {
Navigator.push<String>(
context,
new MaterialPageRoute(
builder: (BuildContext context) {
return new ForgetPwdPage(pwd: "123456");
},
),
);
}
2.3 pushAndRemoveUntil 跳轉(zhuǎn)頁(yè)面并銷(xiāo)毀當(dāng)前頁(yè)面
??????Navigator.pushAndRemoveUntil 向下個(gè)頁(yè)面跳轉(zhuǎn)時(shí)添诉,多傳一個(gè)參數(shù)即跳轉(zhuǎn)后的操作屁桑;如:
Navigator.pushAndRemoveUntil(context,
new MaterialPageRoute(
builder: (BuildContext context) {
return new HomePage();
},
), (route) => route == null);
pop 出棧
1. pop 銷(xiāo)毀當(dāng)前頁(yè)面
??????Navigator.pop 可以有一個(gè)參數(shù)或兩個(gè)參數(shù),如果只有一個(gè)參數(shù)栏赴,為上下文環(huán)境蘑斧;如果兩個(gè)參數(shù),第二個(gè)參數(shù)為返回值內(nèi)容须眷,可以為多種類(lèi)型竖瘾。
onPressed: () {
Navigator.pop(context);
// Navigator.pop(context, ['a,b,c']);
// Navigator.pop(context, '這是 HomePage 頁(yè)');
},
2. popAndPushNamed 銷(xiāo)毀當(dāng)前頁(yè)面并跳轉(zhuǎn)指向新的頁(yè)面
??????Navigator.popAndPushNamed 第一個(gè)參數(shù)為上下文環(huán)境,第二個(gè)參數(shù)為靜態(tài)注冊(cè)的跳轉(zhuǎn)頁(yè)面名稱(chēng)花颗;如:
onPressed: () {
Navigator.popAndPushNamed(context, 'forgetPwdRoute');
}
??????Tips: 小菜建議在使用返回值時(shí)捕传,注意上一個(gè)頁(yè)面是否已經(jīng)銷(xiāo)毀,否則會(huì)報(bào)異常扩劝。
then 返回值
??????有了頁(yè)面跳轉(zhuǎn)庸论,就需要傳遞參數(shù)和接收返回內(nèi)容,當(dāng)跳轉(zhuǎn)后的頁(yè)面設(shè)置 Navigator.pop 設(shè)置返回值時(shí)棒呛,用 then 關(guān)鍵詞可以接收聂示,測(cè)試如下:
// MyApp()
onPressed: () {
// Navigator.pushNamed(context, 'homeRoute').then((Object result) {}
Navigator.push<Object>(context, new MaterialPageRoute(
builder: (BuildContext context) {
return new HomePage();
})).then((Object result) {
showDialog(
context: context,
builder: (BuildContext context) {
String str = result.toString();
return new AlertDialog(
content: new Text("您返回的內(nèi)容為:$str"),
);
},
);
});
}
// HomePage()
onPressed: () {
Navigator.pop(context, ['a,b,c']);
}
主要源碼
跳轉(zhuǎn)頁(yè)面:
onPressed: () {
// 按 name 方式跳轉(zhuǎn)頁(yè)面
// Navigator.pushNamed(context, 'homeRoute');
// 按 name 方式跳轉(zhuǎn)頁(yè)面,并接收返回值
// Navigator.pushNamed(context, 'homeRoute').then((Object result) {
// showDialog(
// context: context,
// builder: (BuildContext context) {
// String str = result.toString();
// return new AlertDialog(
// content: new Text("您返回的內(nèi)容為:$str"),
// );
// },
// );
// });
// 按 name 方式跳轉(zhuǎn)頁(yè)面簇秒,并銷(xiāo)毀當(dāng)前頁(yè)面
// Navigator.pushNamedAndRemoveUntil(
// context, "homeRoute", (route) => route == null);
// 直接 push 方式跳轉(zhuǎn)頁(yè)面
// Navigator.push<Object>(
// context,
// new MaterialPageRoute(
// builder: (BuildContext context) {
// return new HomePage();
// },
// ),
// );
// 直接 push 方式跳轉(zhuǎn)頁(yè)面,并接收返回內(nèi)容
Navigator.push<Object>(context, new MaterialPageRoute(
builder: (BuildContext context) {
return new HomePage();
})).then((Object result) {
showDialog(
context: context,
builder: (BuildContext context) {
String str = result.toString();
return new AlertDialog(
content: new Text("您返回的內(nèi)容為:$str"),
);
},
);
});
// 直接 push 方式跳轉(zhuǎn)頁(yè)面宰睡,并銷(xiāo)毀當(dāng)前頁(yè)面
// Navigator.pushAndRemoveUntil(context,
// new MaterialPageRoute(
// builder: (BuildContext context) {
// return new HomePage();
// },
// ), (route) => route == null);
}
跳轉(zhuǎn)頁(yè)面并傳參
onTap: () {
// 單純跳轉(zhuǎn)頁(yè)面
// Navigator.pushNamed(context, "forgetPwdRoute");
// 傳遞參數(shù)
Navigator.push<String>(
context,
new MaterialPageRoute(
builder: (BuildContext context) {
return new ForgetPwdPage(pwd: "123456");
},
),
);
},
銷(xiāo)毀頁(yè)面
onPressed: () {
// pop 一個(gè)參數(shù)蒲凶,銷(xiāo)毀當(dāng)前頁(yè)面
// Navigator.pop(context);
// pop 兩個(gè)參數(shù),返回一個(gè)數(shù)組
// Navigator.pop(context, ['a,b,c']);
// pop 兩個(gè)參數(shù)拆内,返回一個(gè)字符串
Navigator.pop(context, 'HomePage');
// popAndPushNamed 銷(xiāo)毀當(dāng)前頁(yè)面并跳轉(zhuǎn)新的頁(yè)面
// Navigator.popAndPushNamed(context, 'forgetPwdRoute');
},
??????GitHub Demo
??????小菜剛接觸 Flutter 時(shí)間不長(zhǎng)旋圆,還有很多不清楚和不理解的地方,如果又不對(duì)的地方還希望多多指出麸恍。
來(lái)源:阿策小和尚