Flutter路由管理

Yinll發表於2018-11-07

版權宣告:本文為博主原創文章,轉載請註明出處!juejin.im/post/5be2d6…

轉眼接觸Flutter也有個多月了,專案也在算是上線了(一把辛酸一把淚啊),趁這幾天有點時間,趕緊整理了一波,也是第一次在掘金髮文,後續會繼續保持更新的,如果覺得還行,希望能點點贊啥的,哈哈! 今天跟大家聊聊Flutter中非常重要的一個東西:路由 這是不得不好好研究和學習的一個知識點,用的不好會讓你非常的頭疼,也會給你造成非常多的問題。

第一點: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(),
        },
      )
  );
}
複製程式碼

使用:Navigator.of(context).pushNamed('/screen1'); 直接進入screen1頁面(每次都將新建一個新的頁面)

2.1 pushReplacementNamed——Navigator.of(context).pushReplacementNamed('/screen4');
複製程式碼

指把當前頁面在棧中的位置替換成跳轉的頁面(替換導航器的當前路由,通過推送路由[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.
複製程式碼

即比如當前從頁面1進入頁面2,在頁面2使用 Navigator.of(context).pushReplacementNamed('/screen3');進入頁面3,當進入了頁面3後,頁面2將執行dispose方法,此時在頁面3返回時,會回到頁面1.

使用情況:例如 從SplashScreen到HomeScreen。它應該只顯示一次,使用者不應該再從主螢幕回到它。在這種情況下,由於我們將要進入一個全新的螢幕, 我們可能想要使用這個方法來實現它的enter animation屬性。

2.2  pushReplacement——Navigator.pushReplacement( context, MaterialPageRoute(builder: (BuildContext context) => screen4()));
複製程式碼

這個用法跟2.1相同,只是路由的傳遞有差別,上方的是傳遞路由名稱(頁面對應的名稱,需在入口定義(本文第一點)),而後者只需new對應頁面即可,而且可以傳遞 引數(傳參方式類似於本文後續所說的傳遞方法)。

3.popAndPushNamed——Navigator.popAndPushNamed(context, '/screen4');
複製程式碼

指將當前頁面pop,然後跳轉到制定頁面(將當前路由彈出導航器,並將命名路由推到它的位置。) 下面為官方說明:

Pop the current route off the navigator that most tightly encloses the
given context and push a named route in its place.
複製程式碼

使用情況:例如 在購物應用中,有產品列表,使用者在產品列表中可以通過篩選,來進一步選擇商品,在這個過程中,使用者點選篩選按鈕時,會進入篩選條件選擇介面,當使用者點選 確定篩選按鈕時,應彈出篩選介面,並使用新的篩選條件進入產品列表。這種情況popAndPushNamed就更合適了。

4.pushNamedAndRemoveUntil——Navigator.of(context).pushNamedAndRemoveUntil('/screen4', (Route<dynamic> route) => false);
複製程式碼

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

Push the route with the given name onto the navigator, and then remove all
the previous routes until the `predicate` returns true.
複製程式碼

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

5.1 pushNamedAndRemoveUntil——Navigator.of(context).pushNamedAndRemoveUntil('/screen4', ModalRoute.withName('/screen1'));
複製程式碼

指將制定的頁面加入到路由中,然後將之前的路徑移除知道制定的頁面為止(將具有給定名稱的路由推到導航器上,然後刪除所有路徑前面的路由直到'predicate'返回true為止。) 這時候將銷燬棧內除了screen4的頁面,點選直接去棧內screen4,這時screen4會重新build

Push the route with the given name onto the navigator, and then remove all
the previous routes until the `predicate` returns true.
複製程式碼

使用情況:例如 一個購物應用程式的例子!或者任何需要支付交易的應用程式。因此,在這些應用程式中,一旦使用者完成了支付事件,所有與交易或購物車相關的螢幕都應該從堆疊中刪除,使用者應該進入到支付確認頁面。單擊back按鈕應將它們返回到產品列表或主螢幕。 使用例項: 1-->2-->3,3到4時使用Navigator.pushNamedAndRemoveUntil(context,"/screen4",ModalRoute.withName('/screen1')); 這時候如果在頁面4點選返回,將會直接退出程式。 1-->2-->3,3到4時使用Navigator.pushNamedAndRemoveUntil(context,"/screen4",ModalRoute.withName('/')); 這時候如果在頁面4點選返回,將會直接回到頁面1。 1-->2-->1-->2-->3,3到4時使用Navigator.pushNamedAndRemoveUntil(context,"/screen4",ModalRoute.withName('/screen1')); 這時候如果在頁面4點選返回,將會回到第二個1頁面。

5.2

  Navigator.pushAndRemoveUntil(
  context,
  MaterialPageRoute(builder: (BuildContext context) => new  screen4()),
  ModalRoute.withName('/'),
複製程式碼

這種方法跟上述方法作用相同,不同之處在於,上述傳遞的是路由名稱,這個名稱需要你在入口處進行路由指定,而這種則無需指定,直接new 出來即可, 而且可以傳遞引數。(看其名稱即可發現差別pushNamedAndRemoveUntil與pushAndRemoveUntil)使用這種作用如下 1-->2-->3,3到4時使用此方法,這時候如果在頁面4點選返回,將會直接回到頁面1。

如果使用

Navigator.pushAndRemoveUntil(
    context,
    MaterialPageRoute(builder: (BuildContext context) => Screen4()),
      (Route<dynamic> route) => false,
);
複製程式碼

這時候進入4後。4將成為唯一的一個頁面。其他頁面都將pop出棧,這個跟上述pushNamedAndRemoveUntil也一致。

6.popUntil——Navigator.popUntil(context, ModalRoute.withName('/screen2'));
複製程式碼

有些應用場景下,使用者可能不得不填寫一個由三部分組成的長表單,該表單可能在移動應用程式的三個連續螢幕中顯示。現在在表單的第三個頁面,使用者決定取消填寫表單。使用者單擊Cancel,就會彈出所有之前的與表單相關的螢幕,並將使用者帶回主螢幕,從而丟失所有與表單相關的資料(在這種情況下,這是我們想要的)。我們不會在這裡推出任何新東西,只是回到以前的路線。

第二點 pop

1.Navigator.of(context).maybePop();
複製程式碼

maybePop 會自動進行判斷,如果當前頁面pop後,會顯示其他頁面,不會出現問題,則將執行當前頁面的pop操作 否則將不執行。

2.Navigator.of(context).canPop();
複製程式碼
canPop  判斷當前頁面能否進行pop操作,並返回bool值
複製程式碼
3.Navigator.of(context).pop();
   直接退出當前頁面
複製程式碼

第三點 傳參和引數返回

傳參的方式很簡單,在需要接收引數的頁面進行引數定義,並加入其建構函式中,在跳轉到該頁面時,使用MaterialPageRoute並在頁面中傳入引數即可。

String params;
 Navigator.push(context, new MaterialPageRoute(builder: (BuildContext context) => new mainPage(params)));
接收引數
class mainPage extends StatelessWidget {
  final String userName;
  mainPage(this.userName);
  @override
  Widget build(BuildContext context) {
    print(userName);
}
複製程式碼

帶返回值的頁面跳轉:

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

然後screen5中,在返回時使用:Navigator.of(context).pop('這是頁面5返回的引數'); 在pop中寫上返回的的值,這時候在上方的then中即可得到返回的資料。

好啦 小夥伴們,今天就先說這麼多,,後續我也會保持用法的不斷更新,可以點下關注,以便及時得到更新通知哦。哈哈! 作為剛入坑Flutter的我而言,有些說的可能也存在錯誤,歡迎批評指正!

程式碼來啦Github傳送門 喜歡的話,麻煩點點star哦!

相關文章