[Xamarin][筆記]Navigation機制

  • 1144
  • 0

使用手機APP時,因為螢幕小的關係,一個功能通常都需要切換多個畫面才能處理完整。所以,頁面切換(Navigation)是Xamarin很重要的機制。

 

這篇是研究Xamarin官網-Hierarchical Navigation的筆記

NavigationPage Class物件是用來提供App的頁面切換的機制,每一個頁面是使用後進先出(LIFO)的stack結構。

以下的截圖顯示了在不同的平台上NavigationPage的幾個主要元件的模樣 Components of the NavigationPage

當一個頁面切換到另一個頁面時,背後的機制是Push一個新頁面到navigation stack上。

push navigation stack

當返回上一個頁面時,則是由navigation stackPop目前的頁面

pop navigation stack

頁面切換

Creating the Root Page

navigation stack的第一頁面就是application的root page,其加入方式如以下程式碼

public App ()
{
  MainPage = new NavigationPage (new Page1Xaml ());
}

Pushing Pages to the Navigation Stack

如果要切換頁面,則是透過呼叫目前頁面物件的Navigation屬性的PushAsyncmethod

async void OnNextPageButtonClicked (object sender, EventArgs e)
{
  await Navigation.PushAsync (new Page2Xaml ());
}

上面的Code會建立一個Page2Xaml的instance,將其加入navigation stack中,並設定它為運作中頁面。

PushAsync method被呼叫時,會觸發底下幾個event

  • 當下的頁面的 OnDisappearing method 會被呼叫
  • 被加進來的頁面的 OnAppearing method 會被呼叫
  • The PushAsync task completes

Popping Pages from the Navigation Stack

如果是要切換回來上一個頁面,可以使用手機上的Back按鈕,畫面上的或是實體按鈕都行。

也可以透過程式碼進行控制

async void OnPreviousPageButtonClicked (object sender, EventArgs e)
{
  await Navigation.PopAsync ();
}

這會讓原先的頁面由navigation stack被移除掉,並切換為上一個頁面

PopAsync method被呼叫時,會觸發底下幾個event

  • 當下的頁面的 OnDisappearing method 會被呼叫
  • 所返回頁面的 OnAppearing method 會被呼叫
  • The PopAsync task completes

頁面切換時傳遞資料

有時候會需要再切換頁面時,傳遞資料給目標頁面。這樣的需求,可以透過以下兩種方式來解決。

透過建構式傳遞資料

在目標頁面的建構式中設計參數以接受原頁面所給的資料,如以下程式碼:

public App ()
{
  MainPage = new NavigationPage (new MainPage (DateTime.Now.ToString ("u")));
}

這樣MainPage就可以透過建構式取得資料了

public MainPage (string date)
{
  InitializeComponent ();
  dateLabel.Text = date;
}

透過BindingContext傳遞資料

另一個方式,是透過設定目標頁面的BindingContext屬性以傳遞資料,如以下的程式碼:

async void OnNavigateButtonClicked (object sender, EventArgs e)
{
  var contact = new Contact {
    Name = "Jane Doe",
    Age = 30,
    Occupation = "Developer",
    Country = "USA"
  };

  var secondPage = new SecondPage ();
  secondPage.BindingContext = contact;
  await Navigation.PushAsync (secondPage);
}

這樣子帶來的好處是,目標頁面就可以使用Data Binding的方式顯示資料

操作Navigation Stack

除了上述的PushAsync method 與 PopAsync method之外,還有兩個method可以讓我們操作Navigation Stack - InsertPageBeforeRemovePage

InsertPageBefore method可以插入一個頁面到現存的某一頁面之前,如下圖所示:

InsertPageBefore

RemovePage method則可以由Navigation Stack中移除特定的頁面

RemovePage

這些method可以讓頁面切換的控制更自由,例如當登入成功時,可以插入一個新頁面,並Pop原登入畫面,以達成登入成功的使用者體驗。

async void OnLoginButtonClicked (object sender, EventArgs e)
{
  ...
  var isValid = AreCredentialsCorrect (user);
  if (isValid) {
    App.IsUserLoggedIn = true;
    Navigation.InsertPageBefore (new MainPage (), this);
    await Navigation.PopAsync ();
  } else {
    // Login failed
  }
}