Flutter基礎(chǔ): 路由管理

Flutter的設(shè)計(jì)貌似對(duì)前端同學(xué)比較友好蔗崎,言歸正傳,先從原理開(kāi)始,然后是具體的case,好侮腹,我們開(kāi)始:

小提示:電腦端閱讀更佳

1. 路由工作原理:

對(duì)于原來(lái)移動(dòng)端開(kāi)發(fā)的同學(xué),多了件事情稻励,管理路由父阻。簡(jiǎn)單講路由的工作原理是通過(guò)路由對(duì)象的進(jìn)出棧來(lái)使用戶從一個(gè)頁(yè)面跳轉(zhuǎn)到另一個(gè)頁(yè)面。

2. 路由是什么望抽?

在Flutter 中理解好路由(Route), 離不開(kāi)另一個(gè)概念導(dǎo)航(Navigator), Flutter中路由管理, 主要依賴的是 Navigator(導(dǎo)航器)類, 這是一個(gè)用于管理一組具有某種進(jìn)出規(guī)則的頁(yè)面的 Widget, 也就是說(shuō)用它我們能夠?qū)崿F(xiàn)各個(gè)頁(yè)面間有規(guī)律的切換, 而這里的規(guī)則便是在其內(nèi)部維護(hù)的一個(gè)“ 路由棧加矛。

3. 路由的種類:

路由分為 組件路由,命名路由煤篙,自定義路由斟览,嵌套路由。

4. 使用方法:

Navigator:導(dǎo)航器,負(fù)責(zé)管理路由
路由名稱命名:路由名稱通常使用路徑結(jié)構(gòu):“/a/b/c”辑奈,主頁(yè)默認(rèn)為 “/”苛茂。

4.1 PUSH 使用

1. pushNamed
Navigator.of(context).pushNamed('routeName');
簡(jiǎn)單的將我們需要進(jìn)入的頁(yè)面push到棧頂已烤,以此來(lái)顯示當(dāng)前頁(yè)面,其參數(shù)是一個(gè)字符串類型,傳入的是頁(yè)面對(duì)應(yīng)的路由名稱 該路由名稱需要在程序主入口中進(jìn)行定義:

void main() {
  runApp(
    new MaterialApp(
         home: new Screen1(),
         routes: <String, WidgetBuilder> {
          '/screen1': (BuildContext context) => new Screen1(),
          '/screen2': (BuildContext context) => new Screen2(),  
          '/screen3': (BuildContext context) => new Screen3(),
 },   ));}

2.pushReplacementNamed
Navigator.of(context).pushReplacementNamed('routeName');

指把當(dāng)前頁(yè)面在棧中的位置替換成跳轉(zhuǎn)的頁(yè)面(替換導(dǎo)航器的當(dāng)前路由妓羊,通過(guò)推送路由[routeName])胯究,當(dāng)新的頁(yè)面進(jìn)入后,之前的頁(yè)面將執(zhí)行dispose方法躁绸。

下面為官方說(shuō)明:
Replace the current route of the navigator that most tightly encloses the given context by pushing the route named [routeName] and then disposing the previous route once the new route has finished animating in.

Case Study:
從SplashScreen到HomeScreen裕循。它應(yīng)該只顯示一次,用戶不應(yīng)該再?gòu)闹髌聊换氐剿茄铡T谶@種情況下费韭,由于我們將要進(jìn)入一個(gè)全新的屏幕, 我們可能想要使用這個(gè)方法來(lái)實(shí)現(xiàn)它的enter animation屬性庭瑰。

3.pushReplacement
特點(diǎn):可以通信星持,頁(yè)面間傳遞參數(shù)

Navigator.pushReplacement( context, MaterialPageRoute(builder: (BuildContext context) => screen4(param)));

4. popAndPushNamed
Navigator.popAndPushNamed(context, 'routeName');

指把當(dāng)前頁(yè)面在棧中的位置替換成跳轉(zhuǎn)的頁(yè)面(替換導(dǎo)航器的當(dāng)前路由,通過(guò)推送路由[routeName])弹灭,當(dāng)新的頁(yè)面進(jìn)入后督暂,之前的頁(yè)面將執(zhí)行dispose方法。

下面為官方說(shuō)明:
Replace the current route of the navigator that most tightly encloses the given context by pushing the route named [routeName] and then disposing the previous route once the new route has finished animating in.

Case Study:
例如 在購(gòu)物應(yīng)用中穷吮,有產(chǎn)品列表逻翁,用戶在產(chǎn)品列表中可以通過(guò)篩選,來(lái)進(jìn)一步選擇商品捡鱼,在這個(gè)過(guò)程中八回,用戶點(diǎn)擊篩選按鈕時(shí),會(huì)進(jìn)入篩選條件選擇界面驾诈,當(dāng)用戶點(diǎn)擊 確定篩選按鈕時(shí)缠诅,應(yīng)彈出篩選界面,并使用新的篩選條件進(jìn)入產(chǎn)品列表乍迄。這種情況popAndPushNamed就更合適了管引。

5. pushNamedAndRemoveUntil
Navigator.of(context).pushNamedAndRemoveUntil('routeName', (Route<dynamic> route) => false);

指將制定的頁(yè)面加入到路由中,然后將其他所有的頁(yè)面全部pop, (Route route) => false將確保刪除推送路線之前的所有路線闯两。 這時(shí)候?qū)⒋蜷_(kāi)一個(gè)新的routeName頁(yè)

Case Study:
使用情況:例如 當(dāng)用戶點(diǎn)擊了退出登錄時(shí)褥伴,我們需要進(jìn)入某一個(gè)頁(yè)面(比如點(diǎn)退出登錄后進(jìn)入了登錄頁(yè)),這個(gè)時(shí)候用戶點(diǎn)擊返回時(shí)不應(yīng)該能進(jìn)入任何一個(gè)頁(yè)面漾狼,這種情況就可以使用重慢。

6. pushAndRemoveUntil
Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (BuildContext context) => new screen4()), ModalRoute.withName('/'))

7. popUntil
Navigator.popUntil(context, ModalRoute.withName('routeName'));

4.2 POP 使用

1. maybePop
Navigator.of(context).maybePop();

maybePop 會(huì)自動(dòng)進(jìn)行判斷,如果當(dāng)前頁(yè)面pop后逊躁,會(huì)顯示其他頁(yè)面伤锚,不會(huì)出現(xiàn)問(wèn)題,則將執(zhí)行當(dāng)前頁(yè)面的pop操作 否則將不執(zhí)行。

Case Study:
如果我們?cè)诔跏悸酚缮喜⑶矣腥隋e(cuò)誤地試圖彈出這個(gè)唯一頁(yè)面怎么辦屯援? 彈出堆棧中唯一的頁(yè)面將關(guān)閉您的應(yīng)用程序,因?yàn)樗竺嬉呀?jīng)沒(méi)有頁(yè)面了念脯。這顯然是不好的體驗(yàn)狞洋。 這就是 maybePop() 起的作用。

2.canPop
Navigator.of(context).canPop();

canPop 判斷當(dāng)前頁(yè)面能否進(jìn)行pop操作绿店,并返回bool值

3.pop
Navigator.of(context).pop();

直接退出當(dāng)前頁(yè)面

4.3 Popup routes(彈出路由)

路由不一定要遮擋整個(gè)屏幕

4.4 自定義路由

創(chuàng)建自己的一個(gè)窗口z組件庫(kù)路由類(如 PopupRoute吉懊,ModalRoute 或 PageRoute)的子類
可以做什么:
- 動(dòng)畫
- 路徑的動(dòng)畫
- 路徑的模態(tài)屏障的顏色
- 行為以及路徑的其他各個(gè)特性

Navigator.push(context, PageRouteBuilder(

  opaque: false, //這個(gè)屬性不會(huì)遮擋屏幕

  pageBuilder: (BuildContext context, _, __) {return Center(child: Text('My PageRoute'));},
 
  transitionsBuilder: (___, Animation<double> animation, ____, Widget child) {

  return FadeTransition(

     opacity: animation,

     child: RotationTransition(

         turns: Tween<double>(begin: 0.5, end: 1.0).animate(animation),

         child: child,),

);}));
4.5 嵌套路由

一個(gè)應(yīng)用程序可以使用多個(gè)路由導(dǎo)航器。將一個(gè)導(dǎo)航器嵌套在另一個(gè)導(dǎo)航器下方可用于創(chuàng)建“內(nèi)部旅程”

4.6 數(shù)據(jù)傳遞和數(shù)據(jù)返回(頁(yè)面間的通信)

1. 數(shù)據(jù)傳遞
Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context) => new mainPage(params)));

  • 在需要接收參數(shù)的頁(yè)面進(jìn)行參數(shù)定義
  • 將參數(shù)添加到構(gòu)造函數(shù)中
  • 使用MaterialPageRoute并在頁(yè)面中傳入?yún)?shù)即可

2.數(shù)據(jù)返回

2.1 Navigator.of(context).pop('這是頁(yè)面5返回的參數(shù)'); 在pop中寫上返回的的值假勿,這時(shí)候在上方的then中即可得到返回的數(shù)據(jù)借嗽。

2.2

方法一:

String userName = "yinll";
Navigator.push( context, new MaterialPageRoute( 
      builder: (BuildContext context) => 
        new Screen5(userName)))
        .then(
            (data){ result =data; print(result); 
});

方法二:

onTap: () async {
         String result = await Navigator.push( context, new MaterialPageRoute( 
                builder: (context) => new ContentScreen(articles[index]), ), );
                if (result != null) { 
                    Scaffold.of(context).showSnackBar( 
                            new SnackBar( content: new Text("$result"), duration: const Duration(seconds: 1), ), ); 
}}
最佳實(shí)踐(實(shí)用):
  1. 認(rèn)識(shí)路由,一個(gè)輕量級(jí)的路由管理本質(zhì)是頁(yè)面標(biāo)識(shí)(頁(yè)面路徑)與頁(yè)面實(shí)例的映射

  2. 傳統(tǒng)的做法弊端

    1. 每個(gè)映射的維護(hù)影響全局映射配置的穩(wěn)定性转培,每次維護(hù)映射管理時(shí)需要腦補(bǔ)所有的邏輯分支.

    2. 無(wú)法做到頁(yè)面的統(tǒng)一抽象恶导,頁(yè)面的構(gòu)造器和構(gòu)造邏輯被開(kāi)發(fā)者自定義.

    3. 映射配置無(wú)法與頁(yè)面聯(lián)動(dòng),把頁(yè)面級(jí)的配置進(jìn)行中心化的維護(hù)浸须,導(dǎo)致維護(hù)責(zé)任人缺失.

  3. 最佳實(shí)踐:路由注解方案(這里是一位阿里同學(xué)給出的方案)

    1. annotation_route

    2. 注解方案設(shè)計(jì)圖


      image.png

參考鏈接:

  [https://medium.com/flutter-community/flutter-push-pop-push-1bb718b13c31](https://medium.com/flutter-community/flutter-push-pop-push-1bb718b13c31)

  [https://juejin.im/post/5be2d6546fb9a049be5cf6d5#heading-0](https://juejin.im/post/5be2d6546fb9a049be5cf6d5#heading-0)

  [https://juejin.im/post/5bbaf7bf5188255c8d0fe309#heading-9](https://juejin.im/post/5bbaf7bf5188255c8d0fe309#heading-9)

  [https://blog.csdn.net/mayness/article/details/85762966](https://blog.csdn.net/mayness/article/details/85762966)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子仔燕,更是在濱河造成了極大的恐慌颠毙,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肌索,死亡現(xiàn)場(chǎng)離奇詭異蕉拢,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)诚亚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門晕换,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人亡电,你說(shuō)我怎么就攤上這事届巩。” “怎么了份乒?”我有些...
    開(kāi)封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵恕汇,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我或辖,道長(zhǎng)瘾英,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任颂暇,我火速辦了婚禮缺谴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘耳鸯。我一直安慰自己湿蛔,他們只是感情好膀曾,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著阳啥,像睡著了一般添谊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上察迟,一...
    開(kāi)封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天斩狱,我揣著相機(jī)與錄音,去河邊找鬼扎瓶。 笑死所踊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的概荷。 我是一名探鬼主播秕岛,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼乍赫!你這毒婦竟也來(lái)了瓣蛀?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤雷厂,失蹤者是張志新(化名)和其女友劉穎惋增,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體改鲫,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡诈皿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了像棘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片稽亏。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖缕题,靈堂內(nèi)的尸體忽然破棺而出截歉,到底是詐尸還是另有隱情,我是刑警寧澤烟零,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布瘪松,位于F島的核電站,受9級(jí)特大地震影響锨阿,放射性物質(zhì)發(fā)生泄漏宵睦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一墅诡、第九天 我趴在偏房一處隱蔽的房頂上張望壳嚎。 院中可真熱鬧,春花似錦、人聲如沸烟馅。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)焙糟。三九已至口渔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間穿撮,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工痪欲, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悦穿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓业踢,卻偏偏與公主長(zhǎng)得像栗柒,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子知举,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容

  • 路由初體驗(yàn) 路由(Routes)是什么雇锡?路由是屏幕或應(yīng)用程序頁(yè)面的抽象逛钻。 Flutter 使我們能夠優(yōu)雅地管理路由...
    Meandni閱讀 4,236評(píng)論 0 16
  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,346評(píng)論 0 10
  • 我們家的大白菜 五年級(jí)一班吳子涵 說(shuō)到白菜,它可是我們最熟悉不過(guò)的蔬菜了锰提,它的葉片白嫩如玉脂曙痘,看起來(lái)就好吃,真想一...
    童聲童話閱讀 792評(píng)論 0 1
  • 昨晚十一點(diǎn)多休息立肘,今晨六點(diǎn)半起床边坤。中間有淺睡。 昨天李大夫把脈谅年,不但能把出身體狀態(tài)茧痒,還能把出心理狀態(tài)。身體方面:1...
    張玉民閱讀 720評(píng)論 0 7
  • 中午閑暇期間耸峭,大家都在整理自己的東西。 同事A突然像發(fā)現(xiàn)了新大陸一樣淋纲,摸著自己的胳膊劳闹,震驚地說(shuō)道:“你看,我這怎么...
    萍欄閱讀 372評(píng)論 1 7