Xamarin.Forms學習之Page Navigation(一)

  在最初接觸Xamarin.Forms的時候,我是跟着Xamarin官方的名爲「learning-xamarin-ebook」的pdf文檔進行學習的,我在成功運行Hello world程序以後,我開始跟着pdf寫上面的monkey實例,然而我卻遇到了一個問題,我在列表頁點擊某一個Item的時候,不能如示例上面所展現的那樣跳轉到詳細頁面。也正由於此我在官方文檔和電子書中尋找答案,也將本身的學習的東西作個簡單的筆記和分享。安全

  在Froms的中的提供了以下方法用於導航:app

  Task PushAsync(Page page)和Task PushModalAsync(Page page)導航到其餘頁面;less

  Task<Page> PopAsync()和Task<Page> PopModalAsync()返回到前一頁;ide

  這四個方法都被定義在一個INavigation接口中,而VisualElement中又定義了一個名爲Navigation的只讀的INavigation的屬性,其餘Page又直接或間接繼承了這個類。因此咱們能夠在代碼中直接作以下調用:函數

  await Navigation.PushAsync(Page page)學習

  await Navigation.PopAsync()動畫

  然而你要想成功調用這四個導航方法,你必須在App類的構造函數中作一些改變,即便用NavigationPage對你得主頁(MainPage)作一個簡單的封裝,而這也就是我先前跳轉頁面不成功的緣由,以下:ui

  

  爲何要這樣呢?由於畢竟跨平臺,只有這樣才能在各個平臺上實現Page的生命週期,其實就是爲了兼容Android(畢竟英文,有些記得不是太清楚,有問題你們指正)。這四個方法都提供了另外一個重載,都多了一個參數:bool animated(默認爲true),根據參數名,你應該也知道這個參數的做用了,但實際上,默認的跳轉頁面的動畫還算能夠,通用的那種,固然貌似也能夠重寫,在電子書的動畫那章應該有講,不過目前我還沒看。。。。。。this

  好了,在繼續正題以前,還有兩個要點,一是在Froms中的Page在各個平臺中是不同的,一個Froms的Page至關於IOS的view Control,也至關於WP的Page,可是並非Android的Activity,這裏給你們給你們貼一下電子書中的原文,官網中的本身搜一下就行spa

  Programmers familiar with Android architecture are sometimes curious how Xamarin.Forms page navigation integrates with the aspect of Android application architecture known as the activity. A Xamarin.Forms application running on an Android device comprises only one activity, and the page navigation is built on top of that. A ContentPage is a Xamarin.Forms object; it is not an Android activ-ity, or a fragment of an activity.

   也正是由於各個平臺的不一樣,Page中的可重寫的方法的調用順序也多不一樣。這個後面說。第二個就是modal page和modeless page,正常的講在各個平臺都沒有對他們明確的區分和定義,在視覺上最直觀的區別就是默認狀況下(導航欄也是能夠經過設置進行顯示和隱藏)在左上角是否有返回按鈕(WP沒有,WP和Android都有返回的物理按鍵,只不過Android在頁面也有返回鍵),而在代碼中則體現爲跳轉頁面時調用的是PushAsync仍是PushModalAsync方法。以下圖(截得的電子書中的圖):

  

  如上圖左邊是modeless page而右邊則是modal page,正如你所看到的,若是你跳轉的頁面是modeless page在各個平臺,你是不須要在頁面中再提供返回按鍵的,而modal page則有不一樣,因爲WP和Android都有物理的返回按鍵支持,因此若是你在modal page中不提供返回按鈕,也並無關係,然而在IOS中,你必須提供,爲何,固然是由於它沒有提供返回的物理按鍵,只有Home鍵。固然WP和Android的物理返回按鍵也是也已禁用的,若是你存在非要用戶完成某些操做的「流氓」行爲,就是重寫OnBackButtonPressed方法便可,以下:

        protected override bool OnBackButtonPressed() { if(flag) { return base.OnBackButtonPressed(); } return true; }

   而且modal page只能跳轉到另外一個modal page,而modeless page能跳轉到modal page和modeless page。

  如今說一下NavigationPage的經常使用屬性和方法:

  一、BarBackgroundColor和BarTextColor都是Color類型的屬性,看名字就知道其用途,這兩個屬性在IOS和Win10都會生效,在Android上去只有背景色(BarBackgroundColor)會生效.

  代碼以下:  

        public static Page GetMainPage() { var monkeyPage = new MonkeysPage(); return new NavigationPage(monkeyPage) { BarBackgroundColor=Color.Green,BarTextColor=Color.Blue }; }

  如圖(我只有安卓機,因此本身的圖只有安卓的,對比圖我就直接截電子書的,之後都是):

  

  官方免費電子書對比圖以下:

  

  二、SetBackButtonTitle方法,這個只有IOS纔會生效,應爲只有IOS會顯示前一頁的Title。

  三、SetTitleIcon方法,這個在IOS中將替換Title屬性,Android替換圖標。

  以上兩個並不會做用於Windows和WP。

  四、SetHasNavigationBar和SetHasBackButton這兩個就是分別設置是否顯示導航欄和是否顯示導航欄的的返回圖標。

  方法並不能在App中設置,只能在Page的構造函數中設置,調用方式以下:

namespace App3.Views { public partial class DetailsPage : ContentPage { public DetailsPage(Monkey monkey) { InitializeComponent();
       //其餘方法大同小異 NavigationPage.SetHasNavigationBar(this, false); this.BindingContext = monkey; } } }

  

 我們繼續,當咱們調用Push或者Pop方法是返回的老是Task對象,是否是意味着若是咱們使用await來調用方法,會出現等待呢?官方的描述爲:task completes rather quickly。並且官方建議在調用Push或者Pop方法的時候,必定要用await,爲何?由於在某些狀況下page stack是不安全的,我須要使用await來確保已經獲取到了下一個頁面的實例,而且已安全的寫入到了page stack中。若是你在看這篇文章的時候你也F12到了INavigation接口中,你會看到接口內定義了兩個IReadOnlyList<Page>的對象。

  

  IReadOnlyList<T>看名字你就知道他是一個只讀的,可是他跟Stack<T>類似,都是先進後出,或者你就把它看成是Stack<T>理解也行,只不過前者是隻讀的而已。在IOS中ModalStack始終爲空的。

  咱們NavigationPage對象中的CurrentPage的值爲NavigationStack的最後一個進棧的,簡單點就是CurrentPage若是有值,那隻能是modeless page。

  

  在Page對象中咱們還看到了兩個能夠重寫的方法:

  protected virtual void OnDisappearing();

  protected virtual void OnAppearing();

  這兩個方法又是何時執行,執行順序又是什麼?咱們這裏用PushAsync和PushModalAsync:

  一、頁面調用PushAsync或者PushModalAsync一般將會獲取當前頁面的OnDisappearing方法重寫的調用

  二、而後獲取下一個頁面的OnAppearing方法的重寫的調用

  三、PushAsync或者PushModalAsync完成

  而當咱們調用PopAsync或者PopModalAsync的執行順序以下:

  一、頁面調用PopAsync或者PopModalAsync將會獲取當前頁面的OnDisappearing方法重寫的調用

  二、而後一般獲取上一個頁面的OnAppearing方法的重寫的調用

  三、PopAsync或者PopModalAsync完成

  是的,我把」一般「用紅色的標註了,爲何,先前也說過Froms Page並非一個Android的Actively,因此有些不一樣,調用PushModalAsync的時候不會調用OnDisappearing,而調用PopModalAsync的時候是不會調用前一頁的OnAppearing,至於爲何,當我把下一個頁面設置爲透明(在構造函數中設置BackgroupColor=Color.FromRgba(0,0,0,0.5)),而後用modal page的方式導航過去的時候就知道了,以下圖:

    

  是的,如你所見,前一頁並無銷燬,而是存在的,so。。。不須要我再解釋了吧!若是你非要問爲何沒有銷燬,個人答案是:呵呵!

  而在IOS中,OnDisappearing的調用是在一個頁面徹底銷燬的時候,而不是在調用Push或者Pop的時候。

 

  好了,就這麼,艱苦的一年啊!

相關文章
相關標籤/搜索