[ Xamarin ] 淺談導航機制Part 2

上一篇我們說明了 Navigation stack 的機制,並且理解了如何透過程式來操控 Navigation stack 內容,進而返回上一頁或是直接回到 Root Page,接下來我們來看一個比較進階的應用,假設在 App 裡設計了登入頁面以及主功能頁面,而主功能頁面必須是經過登入程序後才會看見的,如果使用者還沒有登入則開啟 App 的第一個頁面就會是 Login Page,反之如果使用者是已經登入的狀態,那麼開啟 App 的第一個頁面就會是 Main Page。

讓我們來思考一下 Navigation stack 的變化,首先如果我們把 Root Page 設定為 Login Page,那麼登入後的主功能頁面 Main Page,是推疊在 Login Page 上,因此這時候的 Navigation stack 會是如下圖所示

接著使用者經由主功能頁面 Main Page再進入到資料清單頁面 List Page,此時 Navigation stack 會形成如下圖所示

根據前一篇所談到的,當我們提供回主頁的返回功能時,會採用 Navigation.PopToRootAsync() 方法直接導回,但由於 Navigation stack 目前的Root Page 會是 Login Page ,因此原本預期應該回到主功能頁面 Main Page,反而變成是回到 Login Page 頁面了,這顯然不是我們所想要的,我們所期望的應該是如下圖所示的機制

或許你可能會想說可以直接在 Login Page 裡寫程式邏輯判斷,如果是登入狀態,就再導到 Main Page 不就可以解決了,但這樣一來會讓 Navigation stack 更混亂,所以如果能直接替換掉 Navigation stack 的 Root Page ,那麼應該是最好的選擇,可惜的是 Navigation 目前並沒有可以直接動態指定 Root Page 的方法,但是可以透過插入 Page 的方式來實現替換掉 Root Page ,邏輯上我們可以這樣去思考

(1)當 App 第一次啟用時,使用者尚未登入,所以起始頁面是 Login Page ,此時 Navigation stack 的 Root Page = Login Page

(2)接著當使用者進行登入作業,並且登入成功,此時如果直接跳轉到主功能頁面 Main Page,此時的 Navigation stack 會形成 Login Page (Root Page) + Main Page,如果我們可以把 Main Page 變成插入在 Login Page 前,然後把 Login Page 從 Navigation stack 移除掉,那麼 Navigation stack 就會變成只剩下 Main Page ,自然 Main Page 也就變成是 Root Page 了,那麼在這樣的 Navigation stack 內容之下,從任何其它頁面叫用 Navigation.PopToRootAsync方法,自然也就是回到主功能頁面 Main Page 囉

請考慮以下程式碼,Navigation.InsertPageBefore允許我們以程式碼插入 Page 至 Navigation stack 中,Navigation.InsertPageBefore 方法具有二個參數,分別是要插入的 Page,以及要插入到哪一個 Page

private async void Btn_Login_Clicked(object sender, EventArgs e)
{
	bool verifylogin = true;
	if (verifylogin)
	{
		Navigation.InsertPageBefore(new MainPage(), this);
		await Navigation.PopAsync();
	}
	else
	{
		await DisplayAlert("Alert", "Login fail", "OK");
	}
}

 

最後我們來看實際執行的結果,會看到進入到 Main Page 時,不會出現回上頁的按鍵,就算直接按下手機返回鍵,也是直接回到桌面,而不會是 Login Page ,而 Page2 的 GoRootPage 鍵則是直接回到了 Main Page ,如此一來便可以實現在已登入狀態下,使用者不會因為操作回上頁的按鍵,而返回到登入頁的奇特現象了。

 

 

若本文對您有所幫助,歡迎轉貼,但請在加註【轉貼】及來源出處,並在附上本篇的超連結,感恩您的配合囉。

By No.18