學習目標
- Navigation 頁面導覽
- 導覽的頁面類型 Modaless & ModalPage
- Navigation 的一些屬性
頁面導覽 在資訊界其實很常見,例如你正在看這篇教學所使用的瀏覽器,那左上角的上一頁,就是一種頁面導覽。
如果讓我們以程式的觀點來看待 頁面導覽 ,其實就是 實作堆疊(Stack),
當有新頁面出現時,就將此頁面 Push 進 Stack 並顯示他,
當要回到前一頁時,就 Pop 掉 Stack 第一筆,並顯示最上面一筆的頁面,
而這也是 Xamarin.Forms 實作 Navigation 的方法,
所以會看到 Navigation 類別提供了 Push 和 Pop 的方法,甚至可以手動取得 Navigation Stack 來做進一步處理。
所以會看到 Navigation 類別提供了 Push 和 Pop 的方法,甚至可以手動取得 Navigation Stack 來做進一步處理。
導覽架構內一定有初始頁,我們通常稱作 Main page、Home page 或是 Start page。
而從 Main page 準備導覽時,下一頁的類型我們有兩種可以選擇:
- Modeless page (有返回鈕) - 其實也就是正常的導覽頁面
- Modal page (無返回鈕)
我們會從 Navigation 類別所提供的方法來做介紹,並用範例讓大家了解這兩種頁面類型的差異。
Modeless & Modal 頁面
Navigation 提供兩種方法導覽至下一頁:
- Task PushAsync(Page page)
- Task PushModalAsync(Page page)
而返回也定義了兩個方法 (手動做返回時會寫):
- Task<Page> PopAsync()
- Task<Page> PopModalAsync()
//這邊用了非同步的 Task ,但不代表導覽的頁面是在另一個 Thread 執行,後面的章節會來探討這一部分
Modeless 和 Modal 這兩種頁面類型最大的差別在於
有沒有自動提供返回的按鈕!
為什麼需要無返回鈕的 Modal 頁?
通常用於強制使用者執行完某件事、或輸入完某些資料後,最後才用 Pop 方法導回頁面。
來看範例,
範例包含了三個頁面程式,分別為 MainPage, ModalPage 和 ModelessPage,
我們會在 MainPage 內加入兩個 Button,分別導向其他兩頁:
我們會在 MainPage 內加入兩個 Button,分別導向其他兩頁:
MainPage
public class MainPage : ContentPage { public MainPage() { Title = "Main Page"; Button gotoModelessButton = new Button { Text = "Go to Modeless Page", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.CenterAndExpand }; //導覽至 ModelessPage gotoModelessButton.Clicked += async (sender, args) => { await Navigation.PushAsync(new ModelessPage()); }; Button gotoModalButton = new Button { Text = "Go to Modal Page", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.CenterAndExpand }; //導覽至 ModalPage gotoModalButton.Clicked += async (sender, args) => { await Navigation.PushModalAsync(new ModalPage()); }; Content = new StackLayout { Children = { gotoModelessButton, gotoModalButton } }; } }
*非常重要:如有用到 Navigation,App Class 的 MainPage 要改成這樣:
public class App : Application { public App() { MainPage = new NavigationPage(new MainPage()); } … }
執行結果:
可以注意下 Title 設定的文字會出現在上方
接著點擊 Go to Modeless Page,會導向 ModelessPage:
public class ModelessPage : ContentPage { public ModelessPage() { Title = "Modeless Page"; Button goBackButton = new Button { Text = "Back to Main", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center }; goBackButton.Clicked += async (sender, args) => { await Navigation.PopAsync(); }; Content = goBackButton; } }
*你不一定要實作返回按鈕,Android 和 iOS 上方都已經有現成的返回鈕可以用了…
*Android 和 iOS 上方那一排稱作 Navigation bar
返回到 MainPage 後,讓我們點擊 Go to Modal Page:
public class ModalPage : ContentPage { public ModalPage() { Title = "Modal Page"; Button goBackButton = new Button { Text = "Back to Main", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center }; goBackButton.Clicked += async (sender, args) => { await Navigation.PopAsync(); }; Content = goBackButton; } }
可以注意到 Modal 頁上方的 Navigation bar 不見了~ 連 Title 都沒出來~ 就是不會自動給返回鈕!
特別注意的規則,若要再次導覽時,:
- Modeless page 可以再導向其他 Modeless 或 Modal 頁
- Modal 只能再導到 Modal 頁
這邊介紹一些可以改變 Navigation bar 外觀的屬性,
例如設定背景色或文字顏色:
public class App : Application { public App() { MainPage = new NavigationPage(new MainPage()) { BarBackgroundColor = Color.Blue, BarTextColor = Color.Pink
除了在 App 內設定全域的屬性,
也可以在個別的 Page 內來做設定:
像是個別頁返回鈕消失:
public class ModelessPage : ContentPage { public ModelessPage() { Title = "Modeless Page"; NavigationPage.SetHasBackButton(this, false); … } }
XAML 寫法
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="ModelessAndModal.ModelessPage" Title="Modeless Page" NavigationPage.HasBackButton="False"> … </ContentPage>
還有其他屬性像是:
讓整條 bar 消失:
NavigationPage.SetHasNavigationBar(this, false);
設定返回鈕顯示的字:
NavigationPage.SetBackButtonTitle(this, "go back");
設定 Icon:
NavigationPage.SetTitleIcon(this, "ic_action_flash_on.png");
其實我一直很疑惑為什麼這本書要把 Navigation 放到 24 章,
在我學 Xamarin 的第一天起,我就一直很困惑要怎麼在 App 導向下一個頁面。
直到我讀到 24 章... 微軟你有想過 1 ~ 23 章很遙遠嗎...
好了抱怨完畢。
請問一下,
回覆刪除我在 Tabbed Page 裡做 page navigation,我的 tab bar會被蓋掉耶
是有什麼地方要設定嗎??
謝謝
別理我,我解決了,雖然不是很確定改了什麼...
刪除謝謝
okok,正想問清楚問題哈哈
刪除想要問一下,若是返回上一頁,上一頁有辦法更新嗎?refresh之類的,感恩
回覆刪除建議搭配 MVVM,在頁面 OnAppearing 時重新讀取資料
刪除像是個別頁返回"紐"消失
回覆刪除已修正錯字,感謝
刪除在ModelPage的goBackButton事件中我把PopAsync改成PopModalAsync,否則會報錯。
回覆刪除請問這是為什麼?
看你 push 了什麼頁面,就要 pop 那個型態的頁面。或是你也可以把錯誤訊息貼上來讓我看看
刪除