Flutter基礎: 路由管理

Flutter的設計貌似對前端同學比較友好,言歸正傳,先從原理開始,然后是具體的case,好,我們開始:

小提示:電腦端閱讀更佳

1. 路由工作原理:

對于原來移動端開發的同學,多了件事情,管理路由。簡單講路由的工作原理是通過路由對象的進出棧來使用戶從一個頁面跳轉到另一個頁面。

2. 路由是什么?

在Flutter 中理解好路由(Route), 離不開另一個概念導航(Navigator), Flutter中路由管理, 主要依賴的是 Navigator(導航器)類, 這是一個用于管理一組具有某種進出規則的頁面的 Widget, 也就是說用它我們能夠實現各個頁面間有規律的切換, 而這里的規則便是在其內部維護的一個“ 路由棧。

3. 路由的種類:

路由分為 組件路由,命名路由,自定義路由,嵌套路由。

4. 使用方法:

Navigator:導航器,負責管理路由
路由名稱命名:路由名稱通常使用路徑結構:“/a/b/c”,主頁默認為 “/”。

4.1 PUSH 使用

1. pushNamed
Navigator.of(context).pushNamed('routeName');
簡單的將我們需要進入的頁面push到棧頂,以此來顯示當前頁面,其參數是一個字符串類型,傳入的是頁面對應的路由名稱 該路由名稱需要在程序主入口中進行定義:

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');

指把當前頁面在棧中的位置替換成跳轉的頁面(替換導航器的當前路由,通過推送路由[routeName]),當新的頁面進入后,之前的頁面將執行dispose方法。

下面為官方說明:
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。它應該只顯示一次,用戶不應該再從主屏幕回到它。在這種情況下,由于我們將要進入一個全新的屏幕, 我們可能想要使用這個方法來實現它的enter animation屬性。

3.pushReplacement
特點:可以通信,頁面間傳遞參數

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

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

指把當前頁面在棧中的位置替換成跳轉的頁面(替換導航器的當前路由,通過推送路由[routeName]),當新的頁面進入后,之前的頁面將執行dispose方法。

下面為官方說明:
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:
例如 在購物應用中,有產品列表,用戶在產品列表中可以通過篩選,來進一步選擇商品,在這個過程中,用戶點擊篩選按鈕時,會進入篩選條件選擇界面,當用戶點擊 確定篩選按鈕時,應彈出篩選界面,并使用新的篩選條件進入產品列表。這種情況popAndPushNamed就更合適了。

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

指將制定的頁面加入到路由中,然后將其他所有的頁面全部pop, (Route route) => false將確保刪除推送路線之前的所有路線。 這時候將打開一個新的routeName頁

Case Study:
使用情況:例如 當用戶點擊了退出登錄時,我們需要進入某一個頁面(比如點退出登錄后進入了登錄頁),這個時候用戶點擊返回時不應該能進入任何一個頁面,這種情況就可以使用。

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 會自動進行判斷,如果當前頁面pop后,會顯示其他頁面,不會出現問題,則將執行當前頁面的pop操作 否則將不執行。

Case Study:
如果我們在初始路由上并且有人錯誤地試圖彈出這個唯一頁面怎么辦? 彈出堆棧中唯一的頁面將關閉您的應用程序,因為它后面已經沒有頁面了。這顯然是不好的體驗。 這就是 maybePop() 起的作用。

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

canPop 判斷當前頁面能否進行pop操作,并返回bool值

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

直接退出當前頁面

4.3 Popup routes(彈出路由)

路由不一定要遮擋整個屏幕

4.4 自定義路由

創建自己的一個窗口z組件庫路由類(如 PopupRoute,ModalRoute 或 PageRoute)的子類
可以做什么:
- 動畫
- 路徑的動畫
- 路徑的模態屏障的顏色
- 行為以及路徑的其他各個特性

Navigator.push(context, PageRouteBuilder(

  opaque: false, //這個屬性不會遮擋屏幕

  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 嵌套路由

一個應用程序可以使用多個路由導航器。將一個導航器嵌套在另一個導航器下方可用于創建“內部旅程”

4.6 數據傳遞和數據返回(頁面間的通信)

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

  • 在需要接收參數的頁面進行參數定義
  • 將參數添加到構造函數中
  • 使用MaterialPageRoute并在頁面中傳入參數即可

2.數據返回

2.1 Navigator.of(context).pop('這是頁面5返回的參數'); 在pop中寫上返回的的值,這時候在上方的then中即可得到返回的數據。

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), ), ); 
}}
最佳實踐(實用):
  1. 認識路由,一個輕量級的路由管理本質是頁面標識(頁面路徑)與頁面實例的映射

  2. 傳統的做法弊端

    1. 每個映射的維護影響全局映射配置的穩定性,每次維護映射管理時需要腦補所有的邏輯分支.

    2. 無法做到頁面的統一抽象,頁面的構造器和構造邏輯被開發者自定義.

    3. 映射配置無法與頁面聯動,把頁面級的配置進行中心化的維護,導致維護責任人缺失.

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

    1. annotation_route

    2. 注解方案設計圖


      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)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容

  • 路由初體驗 路由(Routes)是什么?路由是屏幕或應用程序頁面的抽象。 Flutter 使我們能夠優雅地管理路由...
    Meandni閱讀 4,248評論 0 16
  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,386評論 0 10
  • 我們家的大白菜 五年級一班吳子涵 說到白菜,它可是我們最熟悉不過的蔬菜了,它的葉片白嫩如玉脂,看起來就好吃,真想一...
    童聲童話閱讀 796評論 0 1
  • 昨晚十一點多休息,今晨六點半起床。中間有淺睡。 昨天李大夫把脈,不但能把出身體狀態,還能把出心理狀態。身體方面:1...
    張玉民閱讀 722評論 0 7
  • 中午閑暇期間,大家都在整理自己的東西。 同事A突然像發現了新大陸一樣,摸著自己的胳膊,震驚地說道:“你看,我這怎么...
    萍欄閱讀 374評論 1 7