Flutter之Navigator解讀

美味的小布丁發表於2019-09-12

簡述

本文適合對Flutter已經有簡單瞭解的初學者

官網之Navigator

官網洋洋灑灑的寫了好長一頁, 對於初學者十分的不友好,小編的英文水平可能還停留在nice to meet your 的地步.這個欄目我打算省略...但是我勝在有谷歌翻譯(真沒在打廣告)

我還是簡單粗略的解讀(翻譯)一下,在說Navigator之前是我們先簡單說一下Flutter中的Router的概念

Router

路由是對螢幕介面的抽象。例如,'/home'將帶您進入首頁, '/login'將您帶到登陸頁。 簡單說每一個介面都對應相應的 Page. 我們可以把Router看成一個班級. 每一個學生都是註冊在這個班級上的的人, 通過老師點名, 叫出這個學生, 或者通過老師通過不點名, 通過親手抓的方式, 把學生叫出來 在些次Flutter demo應用程式中我們宣告幾個個路由

MaterialApp(
    title: 'Flutter Demo',
    theme: ThemeData(
        primarySwatch: Colors.blue,
    ),
    home: MyHomePage(title: 'Flutter Demo Home Page'),
    routes: <String, WidgetBuilder> {
        '/xiaoming': (_) => new XiaoMingPage(),
        '/lili': (_) => new LiLiPage(),
    },
);
複製程式碼

Flutter之Navigator解讀

Router的管理

有了學生, 就會涉及學生的管理, 不然每個學生毫無規矩, 整個班級就會很混亂. 有的學生想做在第一排, 有的學生想坐在最後一排, 整個教室將會成為一鍋粥 .這個時候我們今天的主角Navigator就可以登場了.

Navigator

Navigator用來管理堆疊功能(即push和pop)

如果你對堆疊有基本的瞭解,那麼你就知道push和pop, push 是將元素新增到堆疊的頂部,pop是從同一堆疊中刪除頂部元素。

因此,在Flutter的情況下,當我們導航到另一個螢幕時,我們使用Navigator.push方法將新螢幕新增到堆疊的頂部。當然,這些pop方法會從堆疊中刪除該螢幕。 在此,讓我們以上圖為例,讓我們看看如何從螢幕1移動到螢幕2.

初始狀態:

初始狀態

點選 小明滾出來 進行push小明的介面入棧

小明滾出來

點選頂部回退按鈕或者android的返回按鍵, flutter會預設調取flutter.pop方法, 將 小明介面 彈出

初始狀態2

點選 小麗滾出來 進入push小麗的介面入棧

小麗滾出來
這就是整個上圖棧操作的全過程

總結

其實我還沒寫完

寫到這裡, 大家可能覺得小編說的, 某度一抓一把. 沒什麼乾貨, 小編寫出來純是混臉熟, 那麼接下來乾貨來了.

Flutter之Navigator解讀
我檢視了好多份相關文章, 基本上講講push方法pushName方法這個文章就結束了. 但是flutter的NB之處並不是這二個方法就可以展示的.

靜態方法

以下是Navigator的官網靜態方法, 接下來我將講解其中重點部分.

官網介面

maybePop

如果你在應用首頁(堆疊只有一個元素)直接彈出堆疊中唯一的介面, 恭喜你,明天可以去財務結算了.為了避免發生這種問題,我們可以呼叫maybePop()方法。這個方法, 是可以試著彈彈,彈不走拉倒的方法.

maybePop表情
效果測試:

maybePop效果圖
這是gif中, 最終的幾個按鈕的按鈕的程式碼

// 試試然後成功反回
RaisedButton(
    onPressed: () {
        Navigator.maybePop(context);
    },
    child: Text("棧中測試試maybePop"),
),
// 試試,發現自己是棧裡唯一的元素, 放棄pop
RaisedButton(
    onPressed: () {
        Navigator.maybePop(context);
    },
    child: Text("棧首測試試maybePop"),
),
// 直接退, 然後掛了
RaisedButton(
    onPressed: () {
        Navigator.pop(context);
    },
    child: Text("直接pop()"),
),
複製程式碼

canPop

我把canPop放到maybePop之後去講. 是因為他很簡單(其實我是懶得做demo圖). canPop只有在棧中只有一個元素的時候返回 false, 其它都是 true.

Flutter之Navigator解讀
maybePop可以理解成

Navigator.canPop(context) ? Navigator.pop(context): null;
複製程式碼

push和pushNamed

push與pushNames執行效果相同,只是介面的呼叫方式不同, 都是將一個介面壓入棧中. 區別在於, push是親手把介面扔入棧中, 而pushNames則是通過點名的方式通過router讓介面自己進入棧中.

// push的呼叫方法
Navigator.push(context,  new MaterialPageRoute(
    builder: (context)  {
      return Scaffold(
        appBar: AppBar(
          title: Text('我是新的介面'),
        )
      );
    }
));

// pushNamed的呼叫方法
// 先在Router上定義Page;
routes: <String, WidgetBuilder> {
    '/xiaoming': (_) => new XiaoMingPage(),
}
...
Navigator.pushNamed(context, '/XiaoMingPage');
複製程式碼

pushReplacement 和 pushReplacementNamed

同上, 二者都是用來替代當前棧中棧頂元素. 只是介面的呼叫方式不同. 這點不多說了.效果具體看demo, 在二界測試頁點選按鈕後. 跳轉到新介面, 再次點選反回, 我們回到了首頁

Flutter之Navigator解讀

pushAndRemoveUntil 和 pushNamedAndRemoveUntil

當我們構建一個很複雜的應用,使用者登入,滾動, 檢視各種資訊...使用者想登出並回到首頁,你不能只是簡單地push一個首頁, 在這樣的情況下, 您應該刪除堆疊中的所有路由,以便使用者在登出後無法返回到先前的介面. 官方的Demo中的方法, 回到棧底, 併入棧一個 MyHomePage.

Flutter之Navigator解讀

// flutter sample
void _finishAccountCreation() {
  Navigator.pushAndRemoveUntil(
    context,
    MaterialPageRoute(builder: (BuildContext context) => MyHomePage()),
    ModalRoute.withName('/'),
  );
}
複製程式碼

popUntil

當我們構建一個多表單建立的場景,一個使用者需要按次序在不同 Page 填寫不同的表單, 當使用者填寫至的第三頁時,使用者決定取消填寫表單, 我們期望的邏輯是, 回到填寫表單之前的某一頁。

Flutter之Navigator解讀

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

未完待補充

筆者也是一名初學者. 如有不正確的地方,歡迎指責批判, 筆者 也會隨著更深入的瞭解發現, 完善這份文章.

Demo Code

相關文章