Xamarin.Forms Navigation介紹

一個(gè)常規(guī)的App是由多個(gè)Page組成的得哆,出現(xiàn)多個(gè)Page就會(huì)涉及頁(yè)面跳轉(zhuǎn)問(wèn)題迹辐。Xamarin.Forms頁(yè)面之間的跳轉(zhuǎn)通過(guò)Navigation Stack管理Page呵萨,如頁(yè)面A跳轉(zhuǎn)到頁(yè)面B時(shí)撒犀,會(huì)將B壓入棧定某宪,此時(shí)頁(yè)面B成為活動(dòng)頁(yè)面仿村,執(zhí)行Back操作時(shí),頁(yè)面B從棧定推出使頁(yè)面A重新變?yōu)榛顒?dòng)頁(yè)面缩抡。
每個(gè)應(yīng)用程序都有一個(gè)特殊頁(yè)作為應(yīng)用程序的入口(main page, or the home page, or the start page)奠宜,Xamarin.Forms中由App的MainPage屬性設(shè)置。

INavigation介紹

Xamarin.Forms中頁(yè)面分為Modal pages(模態(tài)頁(yè)面) 和 modeless pages(非模態(tài)頁(yè)面)瞻想,跳轉(zhuǎn)到一個(gè)新的頁(yè)面可以通過(guò)PushAsyncPushModalAsync兩個(gè)方法實(shí)現(xiàn)压真,兩個(gè)方法均傳入一個(gè)Page對(duì)象作為參數(shù)。同樣提供了PopAsyncPopModalAsync兩個(gè)方法返回前一個(gè)頁(yè)面蘑险。PushAsync和PopAsync是對(duì)非模態(tài)頁(yè)面的操作滴肿,PushModalAsync和PopModalAsync操作的是模態(tài)頁(yè)面。PopToRootAsync方法表示回到導(dǎo)航棧低頁(yè)面佃迄。RemovePage方法從導(dǎo)航棧中刪除一個(gè)頁(yè)面泼差。InserPageBefore方法將一個(gè)page插入到指定page之前。通過(guò)這些方法操作Navigation Stack可以在不同Page間跳轉(zhuǎn)呵俏。

關(guān)于PopXXX和Push方法定義返回Task類(lèi)型介紹參考(涉及的OnDisappearing和OnAppearing不在本文不再說(shuō)明):
http://www.cnblogs.com/qiandi/p/5598742.html

當(dāng)我們調(diào)用PushAsync方法時(shí)必須修改App的MainPage屬性為NavigationPage對(duì)象堆缘,否則報(bào)如下異常,使用NavigationPage時(shí)不必在為iOS單獨(dú)設(shè)置Page的Padding屬性解決頁(yè)面和狀態(tài)欄遮蓋問(wèn)題普碎。

PopXXX和PushXXX提供的bool類(lèi)型參數(shù)重載方法設(shè)置為true增加頁(yè)面跳轉(zhuǎn)動(dòng)畫(huà)吼肥。

INavigation定義

INavigation還定義了兩個(gè)IReadOnlyList<Page>類(lèi)型屬性ModalStackNavigationStack,NavigationStack表示非模態(tài)頁(yè)面的集合,PushAsync和PopAsync會(huì)改變NavigationStack的內(nèi)容缀皱,ModalStack表示模態(tài)頁(yè)面的集合PushModalAsync和PopModalAsync會(huì)改變ModalStack的內(nèi)容斗这,這兩個(gè)屬性不能直接修改,且提供了類(lèi)似堆棧的功能啤斗。這兩個(gè)集合不能混合跳轉(zhuǎn)表箭,非模態(tài)頁(yè)面可以導(dǎo)航到模態(tài)頁(yè)面但是模態(tài)頁(yè)面不能導(dǎo)航到非模態(tài)頁(yè)面。
如果用MainPage = new NavigationPage(new Page0());初始化App的MainPage屬性運(yùn)行應(yīng)用程序钮莲,此時(shí)IOS平臺(tái)中ModalStack為空免钻,Android和Windows平臺(tái)ModalStack包含一個(gè)元素(MainPage對(duì)應(yīng)NavigationPage實(shí)例)。三個(gè)平臺(tái)中的NavigationStack集合包均含一個(gè)Page0的實(shí)例崔拥。

《Creating Mobile Apps with Xamarin.Forms》中示例截圖

這些方法均定義在INavigation中伯襟,VisualElement提供了一個(gè)INavigation類(lèi)型只讀屬性Navigation,可以通過(guò)調(diào)用Navigation的方法實(shí)現(xiàn)跳轉(zhuǎn)握童。

頁(yè)面中調(diào)用代碼Navigation.PushAsync(new ModelessPage(), true);

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 activity, or a fragment of an activity.
前面提到的參考鏈接有說(shuō)明姆怪,什么意思自己看看吧!T杓ā稽揭!


NavigationPage介紹

NavigationPage的作用就是導(dǎo)航管理頁(yè)面。

NavigationPage提供的屬性

  • BarBackgroundColor - 獲取肥卡、設(shè)置NavigationPage頂部導(dǎo)航欄的背景色(iOS溪掀、Android、Windows 平臺(tái)有效)步鉴。
  • BarTextColor - 獲取揪胃、設(shè)置NavigationPage頂部導(dǎo)航欄顯示文本顏色(iOS、Windows平臺(tái)有效)氛琢。

不同平臺(tái)效果:

  • CurrentPage - 獲取Navigation Stack最頂部頁(yè)面喊递,不管當(dāng)前顯示頁(yè)面是模態(tài)頁(yè)面還是非模態(tài)頁(yè)面,CurrentPage都表示NavigationStack集合中的最后一項(xiàng)阳似。

when a modal page is active, CurrentPage continues to indicate the last modeless page that was active before navigation to a modal page

NavigationPage提供的BindableProperty

  • HasBackButtonProperty - 是否顯示非模態(tài)頁(yè)面導(dǎo)航欄的返回按鈕(iOS骚勘、Android起作用)
    C#設(shè)置NavigationPage.SetHasBackButton(this, false);
    XAML設(shè)置NavigationPage.HasBackButton="False"
  • HasNavigationBarProperty - 是否顯示導(dǎo)航欄
  • BackButtonTitleProperty - 設(shè)置返回按鈕的文本(僅iOS平臺(tái))
  • TitleIconProperty - 設(shè)置導(dǎo)航欄上顯示圖標(biāo)(iOS平臺(tái)Icon代替Title,Android修改左側(cè)圖標(biāo)顯示撮奏,Windows 無(wú)效)
官方圖片G味铩!畜吊!

屏蔽Android泽疆、Windows Mobile 返回按鍵

Android和Windows Phone會(huì)包含一個(gè)返回鍵,返回鍵提供類(lèi)似PopAsync或PopModalAsync的工能玲献,程序中要屏蔽返回鍵的功能需要重寫(xiě)Page的OnBackButtonPressed方法殉疼。OnBackButtonPressed方法返回true值逗嫡,程序不處理返回按鍵。

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

Page還定義了SendBackButtonPressed方法株依,用來(lái)模擬返回按鈕被按下。調(diào)用該方法與Android按下返回鍵功能類(lèi)似延窜。

官方電子書(shū)中提到“Although this works on iOS and Android, it currently does not work on the Windows Runtime platforms.”這個(gè)方法只對(duì)iOS和Android有效恋腕,Windows Runtime platforms不能正常工作。 實(shí)際測(cè)試iOS無(wú)效逆瑞,Android正常荠藤,Windows 無(wú)法測(cè)試。

頁(yè)面間傳值

一個(gè)應(yīng)用程序會(huì)包含多個(gè)頁(yè)面获高,把數(shù)據(jù)從一個(gè)頁(yè)面?zhèn)鞯搅硪粋€(gè)頁(yè)面該怎么做哈肖?

構(gòu)造函數(shù)傳值

頁(yè)面跳轉(zhuǎn)的PushXXX方法傳入Page頁(yè)面實(shí)例作為參數(shù),可以通過(guò)Page頁(yè)面的構(gòu)造函數(shù)傳入數(shù)據(jù)念秧,如Navigation.PushModalAsync(new DataPage(label.Text));淤井,在DataPage重載的構(gòu)造函數(shù)中在處理接收的數(shù)據(jù)。

屬性方法傳值

根據(jù)頁(yè)面的屬性或調(diào)用方法傳值摊趾。如:

構(gòu)造函數(shù)傳值是單向的不能傳遞返回?cái)?shù)據(jù)币狠,通過(guò)屬性傳值可以從當(dāng)前頁(yè)面向前一個(gè)頁(yè)面?zhèn)髦怠?yīng)從NavigationStack集合中取得前一個(gè)頁(yè)面實(shí)例砾层。

var stack = (App.Current.MainPage as NavigationPage).Navigation.NavigationStack;

int lastIndex = stack.Count - 1;
navigationPage homePage = stack[lastIndex] as navigationPage;

if (homePage == null)
{
    homePage = stack[lastIndex - 1] as navigationPage;
}

homePage.SetText(Value + "頁(yè)面返回?cái)?shù)據(jù)了");

從模態(tài)頁(yè)面跳轉(zhuǎn)到非模態(tài)頁(yè)面和模態(tài)頁(yè)面跳轉(zhuǎn)到模態(tài)頁(yè)面兩種情況漩绵,跳轉(zhuǎn)前的頁(yè)面在NavigationStack中有不同的位置。如果是非模態(tài)頁(yè)面跳轉(zhuǎn)到非模態(tài)頁(yè)面肛炮?又要從ModalStack中獲取前一個(gè)頁(yè)面實(shí)例止吐,所以通過(guò)屬性和方法傳值不推薦!G仍恪碍扔!

Messaging Center傳值

MessagingCenter是一個(gè)靜態(tài)類(lèi),提供了Subscribe秕重、Unsubscribe和Send三個(gè)公開(kāi)的方法蕴忆。Subscribe訂閱接收的消息信息,參數(shù)悲幅、發(fā)送者類(lèi)型等套鹅。Unsubscribe取消訂閱,不在接收消息汰具。Send發(fā)送指定類(lèi)型消息卓鹿。

Messaging Center傳值示例:

數(shù)據(jù)接收頁(yè)面增加消息訂閱代碼:

MessagingCenter.Subscribe<navigationPage, string>(this, "Value", (arg1, arg2) =>
        {
            label.Text = arg2;
        });

Subscribe包含兩個(gè)范型參數(shù),第一個(gè)為消息發(fā)送者類(lèi)型留荔,第二個(gè)為傳遞數(shù)據(jù)類(lèi)型吟孙。Subscribe包含三個(gè)參數(shù)澜倦,第一個(gè)為消息接收者,第二個(gè)參數(shù)為字符串類(lèi)型消息標(biāo)示杰妓,第三個(gè)參數(shù)是一個(gè)lambda表達(dá)式藻治,表示接收到消息后的動(dòng)作。

數(shù)據(jù)傳遞頁(yè)面增加發(fā)送消息代碼:

MessagingCenter.Send<navigationPage, string>(this, "Value", label.Text);

Send兩個(gè)范型參數(shù)與Subscribe方法相同巷挥。Send包含三個(gè)參數(shù)桩卵,第一個(gè)參數(shù)為消息發(fā)送者,第二個(gè)參數(shù)為消息標(biāo)示倍宾,第三個(gè)參數(shù)為傳遞的數(shù)據(jù)對(duì)象雏节。
本示例Send方法應(yīng)在PushAsync后執(zhí)行。PushAsync執(zhí)行前消息沒(méi)有訂閱高职,Send發(fā)送消息此時(shí)沒(méi)有接收者钩乍。

不再接收消息時(shí)應(yīng)該調(diào)用Unsubscribe取消指定消息的訂閱,對(duì)資源回收釋放。本示例取消訂閱代碼添加在Subscribe方法的lambda中怔锌。

MessagingCenter.Unsubscribe<navigationPage, string>(this, "Value");

Strictly speaking, however, unsubscribing shouldn’t be necessary because the MessagingCenter maintains WeakReference objects for subscribers寥粹。
MessagingCenter定義了一個(gè)Dictionary<Tuple<string, Type, Type>, List<Tuple<WeakReference, Action<object, object>>>>類(lèi)型對(duì)象通過(guò)WeakReference管理subscribers,所以Unsubscribe方法不是必須的埃元。

事件傳值

WinForm中常用的傳值形式排作,事件傳值。推薦數(shù)據(jù)回傳時(shí)使用亚情。

Page1 跳轉(zhuǎn)到Page2時(shí)妄痪,Page2添加事件定義:

public EventHandler<string> Value;

Page2 返回Page1 時(shí),觸發(fā)事件:

EventHandler<string> handler = Value;
if (handler != null)
{
    handler(this, "增加返回字符串");
}

Page1 跳轉(zhuǎn)到Page2時(shí)楞件,訂閱Page2的事件:

var page = new Page2();
page.Value += (sender, e) =>
{
        label.Text = e;
};
Navigation.PushAsync(page);

傳遞復(fù)雜數(shù)據(jù)繼承EventArgs實(shí)現(xiàn)傳值

App Class傳值

Xamarin.Forms應(yīng)用程序會(huì)提供一個(gè)App類(lèi)(繼承Application)作為程序的入口衫生,該對(duì)象在應(yīng)用程序運(yùn)行期間一直存在,可以借助App類(lèi)實(shí)現(xiàn)不同頁(yè)面之間數(shù)據(jù)傳遞土浸。

修改App代碼定義屬性保存罪针、獲取數(shù)據(jù)。如:

獲取App類(lèi)實(shí)例可以通過(guò)(App)Application.Current)獲取黄伊±峤矗或著直接定義static 屬性,直接通過(guò)App.Value 傳值还最。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末墓阀,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子拓轻,更是在濱河造成了極大的恐慌斯撮,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扶叉,死亡現(xiàn)場(chǎng)離奇詭異勿锅,居然都是意外死亡帕膜,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)溢十,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)垮刹,“玉大人,你說(shuō)我怎么就攤上這事张弛』牡洌” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,450評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵乌庶,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我契耿,道長(zhǎng)瞒大,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,322評(píng)論 1 293
  • 正文 為了忘掉前任搪桂,我火速辦了婚禮透敌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘踢械。我一直安慰自己酗电,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布内列。 她就那樣靜靜地躺著撵术,像睡著了一般。 火紅的嫁衣襯著肌膚如雪话瞧。 梳的紋絲不亂的頭發(fā)上嫩与,一...
    開(kāi)封第一講書(shū)人閱讀 51,274評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音交排,去河邊找鬼划滋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛埃篓,可吹牛的內(nèi)容都是我干的处坪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼架专,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼同窘!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起部脚,我...
    開(kāi)封第一講書(shū)人閱讀 38,980評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤塞椎,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后睛低,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體案狠,經(jīng)...
    沈念sama閱讀 45,414評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡服傍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了骂铁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吹零。...
    茶點(diǎn)故事閱讀 39,773評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖拉庵,靈堂內(nèi)的尸體忽然破棺而出灿椅,到底是詐尸還是另有隱情,我是刑警寧澤钞支,帶...
    沈念sama閱讀 35,470評(píng)論 5 344
  • 正文 年R本政府宣布茫蛹,位于F島的核電站,受9級(jí)特大地震影響烁挟,放射性物質(zhì)發(fā)生泄漏婴洼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評(píng)論 3 327
  • 文/蒙蒙 一撼嗓、第九天 我趴在偏房一處隱蔽的房頂上張望柬采。 院中可真熱鬧,春花似錦且警、人聲如沸粉捻。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,713評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)肩刃。三九已至,卻和暖如春杏头,著一層夾襖步出監(jiān)牢的瞬間树酪,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,852評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工大州, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留续语,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,865評(píng)論 2 370
  • 正文 我出身青樓厦画,卻偏偏與公主長(zhǎng)得像疮茄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子根暑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容